#!/bin/sh

# 一些状态变量的定义
KILL_MYSQLD=; # 试图kill多余的mysqld_safe程序,1表示需要kill
MYSQLD= # mysqld二进制可执行文件的名称
niceness= # 进程的调度优先级标识 # 下面的变量主要用于标识不使用错误日志和syslog
logging=init # 日志记录状态,init代表初始化
want_syslog= # 标识是否要使用syslog
syslog_tag=
user='mysql' # --user选项值
pid_file= # pid文件的路径
err_log= # 错误日志的路径 # 这两个都是定义的syslog中标志位,在后面需要写入日志到syslog中时使用
syslog_tag_mysqld=mysqld
syslog_tag_mysqld_safe=mysqld_safe trap '' # 不允许程序在终端上被人打断(包括挂起,中断,退出,系统终止的情形) umask # 默认权限770,其他组用户对该程序创建的文件没有任何权限 # defaults变量记载使用的配置文件的信息
defaults=
case "$1" in
--no-defaults|--defaults-file=*|--defaults-extra-file=*)
defaults="$1"; shift
;;
esac # usage()函数:使用--help选项时输出的使用帮助信息
usage () {
cat <<EOF
Usage: $ [OPTIONS]
--no-defaults Don't read the system defaults file
--defaults-file=FILE Use the specified defaults file
--defaults-extra-file=FILE Also use defaults from the specified file
--ledir=DIRECTORY Look for mysqld in the specified directory
--open-files-limit=LIMIT Limit the number of open files
--core-file-size=LIMIT Limit core files to the specified size
--timezone=TZ Set the system timezone
--mysqld=FILE Use the specified file as mysqld
--mysqld-version=VERSION Use "mysqld-VERSION" as mysqld
--nice=NICE Set the scheduling priority of mysqld
--skip-kill-mysqld Don't try to kill stray mysqld processes
--syslog Log messages to syslog with 'logger'
--skip-syslog Log messages to error log (default)
--syslog-tag=TAG Pass -t "mysqld-TAG" to 'logger' All other options are passed to the mysqld program. EOF
exit
} # my_which的作用相当于which,通过检索$PATH中的路径,打印出命令的全路径
# 这个函数就在后面一个地方用到了,就是my_which logger,意思等同于转换logger为/usr/bin/logger
my_which ()
{
save_ifs="${IFS-UNSET}" # 保存当前的内建分隔符,用于后面重置IFS
IFS=: # 使用 : 来分割PATH中的路径
ret=
for file # 这种写法等同于for file in &*
do
for dir in $PATH
do
if [ -f "$dir/$file" ]
then
echo "$dir/$file"
continue # continue 第 层, 这里就是跳出外层循环了
fi
done
ret= # signal an error
break
done # 将设置过的IFS重置回去
if [ "$save_ifs" = UNSET ]
then
unset IFS
else
IFS="$save_ifs"
fi return $ret # Success
} # 日志输出函数,这是个原型,后面被log_error和log_notice函数引用
log_generic () {
# priority 代表日志信息的分类,从后面的两个函数可知有:daemon.error和daemon.notice两种类别
priority="$1"
shift # 日志中记录的msg前缀格式: 时间 + mysqld_safe ,类似于系统日志的记录格式
msg="`date +'%y%m%d %H:%M:%S'` mysqld_safe $*"
echo "$msg"
case $logging in
init) ;; # 初始化状态时,只在命令行输出msg信息,不记录日志
file) echo "$msg" >> "$err_log" ;; # 记录到err_log中
syslog) logger -t "$syslog_tag_mysqld_safe" -p "$priority" "$*" ;; # 使用logger记录到系统日志中
*)
echo "Internal program error (non-fatal):" \
" unknown logging method '$logging'" >&
;;
esac
} # 下面两个函数是对log_generic函数中不同分类的引用
log_error () {
log_generic daemon.error "$@" >&
} log_notice () {
log_generic daemon.notice "$@"
} # 后面就是用它启动的mysqld,通过logging变量区分记录日志的类型,分错误日志和系统日志syslog两种
# 最后的eval命令会解析 $cmd 中的值并执行命令
eval_log_error () {
cmd="$1"
case $logging in
file) cmd="$cmd >> "`shell_quote_string "$err_log"`" 2>&1" ;;
syslog)
cmd="$cmd 2>&1 | logger -t '$syslog_tag_mysqld' -p daemon.error"
;;
*)
echo "Internal program error (non-fatal):" \
" unknown logging method '$logging'" >&
;;
esac
#echo "Running mysqld: [$cmd]"
eval "$cmd"
} # 转义函数,用于在非"a-z","A-Z","",'/','_','.','=','-'的特殊字符前加上一个"\"
# sed中的\1代表引用前面\(\)中匹配的值
shell_quote_string() {
echo "$1" | sed -e 's,\([^a-zA-Z0-9/_.=-]\),\\\1,g'
} # 该函数用于解析配置文件中的选项,并赋值给相应的变量
parse_arguments() {
pick_args=
if test "$1" = PICK-ARGS-FROM-ARGV
then
pick_args=
shift
fi for arg do
# 取出参数值,比如 --port= 结果为: val = 注意这里sed中使用;来分割,等同于/
val=`echo "$arg" | sed -e "s;--[^=]*=;;"`
case "$arg" in
# 将参数值传递给对应的变量
--basedir=*) MY_BASEDIR_VERSION="$val" ;;
--datadir=*) DATADIR="$val" ;;
--pid-file=*) pid_file="$val" ;;
--user=*) user="$val"; SET_USER= ;; # 有些值可能已经在my.cnf配置文件的[mysqld_safe]组下设置了
# 某些值会被命令行上指定的选项值覆盖
--log-error=*) err_log="$val" ;;
--port=*) mysql_tcp_port="$val" ;;
--socket=*) mysql_unix_port="$val" ;; # 接下来这几个特殊的选项在配置文件的[mysqld_safe]组中是必须设置的
# 我没配置这个组,所以就用不到了(使用mysqld中的默认)
--core-file-size=*) core_file_size="$val" ;;
--ledir=*) ledir="$val" ;;
--mysqld=*) MYSQLD="$val" ;;
--mysqld-version=*)
if test -n "$val"
then
MYSQLD="mysqld-$val"
else
MYSQLD="mysqld"
fi
;;
--nice=*) niceness="$val" ;;
--open-files-limit=*) open_files="$val" ;;
--skip-kill-mysqld*) KILL_MYSQLD= ;;
--syslog) want_syslog= ;;
--skip-syslog) want_syslog= ;;
--syslog-tag=*) syslog_tag="$val" ;;
--timezone=*) TZ="$val"; export TZ; ;; # 生效了一下时区设置 --help) usage ;; # 调用了usage函数,输出帮助信息 *)
if test -n "$pick_args"
then
# 将其他命令行参数值附加到$arg的后面
append_arg_to_args "$arg"
fi
;;
esac
done
} ########################################
# 正式工作开始了!!
######################################## #
# 下面两段是在寻找基目录和mysqld所在目录
#
# 找到/usr/local/mysql3306/share/mysql目录,使用relpkgdata来记录相对路径和绝对路径
# 这个grep其实应该是想判断一下share/mysql是不是显示的绝对路径,不知道这么写的意义在哪里。
if echo '/usr/local/mysql3306/share/mysql' | grep '^/usr/local/mysql3306' > /dev/null
then
# 一口气用了三个替换,分别为:
# 第一步:将/usr/local/mysql3306转换为空
# 第二步:将/share/mysql开头的/转换为空
# 第三步:在share/mysql开头加上./,结果即:./share/mysql
relpkgdata=`echo '/usr/local/mysql3306/share/mysql' | sed -e 's,^/usr/local/mysql3306,,' -e 's,^/,,' -e 's,^,./,'`
else
relpkgdata='/usr/local/mysql3306/share/mysql'
fi # 这一段都是在找mysqld文件,分别判断了libexec和bin目录
# 找不到就使用编译时的默认值
MY_PWD=`pwd`
if test -n "$MY_BASEDIR_VERSION" -a -d "$MY_BASEDIR_VERSION"
then
if test -x "$MY_BASEDIR_VERSION/libexec/mysqld"
then
ledir="$MY_BASEDIR_VERSION/libexec"
else
ledir="$MY_BASEDIR_VERSION/bin"
fi
# 这里对errmsg.sys文件进行了判断,个人认为这是为了确认当前目录为一个mysql安装基目录
elif test -f "$relpkgdata"/english/errmsg.sys -a -x "$MY_PWD/bin/mysqld"
then
MY_BASEDIR_VERSION="$MY_PWD"
ledir="$MY_PWD/bin"
elif test -f "$relpkgdata"/english/errmsg.sys -a -x "$MY_PWD/libexec/mysqld"
then
MY_BASEDIR_VERSION="$MY_PWD"
ledir="$MY_PWD/libexec"
else
MY_BASEDIR_VERSION='/usr/local/mysql3306'
ledir='/usr/local/mysql3306/libexec'
fi #
# 接下来是找到配置文件和数据文件目录
# # 找到配置文件目录
# 我的是放在了etc/目录下,mysqld程序是会读取到的
#
# 可以从my_print_defaults脚本中获得默认的读取my.cnf顺序,如下
# Default options are read from the following files in the given order:
# /etc/my.cnf /etc/mysql/my.cnf /home/mysql/mysql_master/etc/my.cnf ~/.my.cnf
# 或者可以使用strace -e open libexec/mysqld >& | grep my.cnf查看
if test -d $MY_BASEDIR_VERSION/data/mysql
then
DATADIR=$MY_BASEDIR_VERSION/data
if test -z "$defaults" -a -r "$DATADIR/my.cnf"
then
defaults="--defaults-extra-file=$DATADIR/my.cnf"
fi
# 接下来找到数据文件的目录
elif test -d $MY_BASEDIR_VERSION/var/mysql
then
DATADIR=$MY_BASEDIR_VERSION/var
# 找不到就用编译时指定的默认值
else
DATADIR=/usr/local/mysql3306/var
fi # 对存在两个配置文件情况进行冲突处理
if test -z "$MYSQL_HOME"
then
if test -r "$MY_BASEDIR_VERSION/my.cnf" && test -r "$DATADIR/my.cnf"
then
# 优先考虑 $MY_BASEDIR_VERSION/my.cnf 文件
log_error "WARNING: Found two instances of my.cnf -
$MY_BASEDIR_VERSION/my.cnf and
$DATADIR/my.cnf
IGNORING $DATADIR/my.cnf" MYSQL_HOME=$MY_BASEDIR_VERSION
elif test -r "$DATADIR/my.cnf"
then
log_error "WARNING: Found $DATADIR/my.cnf
The data directory is a deprecated location for my.cnf, please move it to
$MY_BASEDIR_VERSION/my.cnf"
MYSQL_HOME=$DATADIR
else
MYSQL_HOME=$MY_BASEDIR_VERSION
fi
fi
export MYSQL_HOME #
# 下面是使用bin/my_print_defaults读取my.cnf文件中的配置信息([mysqld] and [mysqld_safe])
# 并且和命令行中传入的参数进行合并 # 先是找到my_print_defaults执行文件 又是各种路径判断
if test -x "$MY_BASEDIR_VERSION/bin/my_print_defaults"
then
print_defaults="$MY_BASEDIR_VERSION/bin/my_print_defaults"
elif test -x ./bin/my_print_defaults
then
print_defaults="./bin/my_print_defaults"
elif test -x /usr/local/mysql3306/bin/my_print_defaults
then
print_defaults="/usr/local/mysql3306/bin/my_print_defaults"
elif test -x /usr/local/mysql3306/bin/mysql_print_defaults
then
print_defaults="/usr/local/mysql3306/bin/mysql_print_defaults"
else
print_defaults="my_print_defaults"
fi # 这个函数可以将一个指定的参数附加到$arg中(在此同时执行了转义操作)
append_arg_to_args () {
args="$args "`shell_quote_string "$1"`
} args= # 这里SET_USER=2是针对下面一条parse_arguments来说的
# 因为如果在紧接着的parse_arugments函数中设置了--user的值,那么SET_USER就会变为1,表示--user以被配置
# 当然如果没有读取到--user的值,就是说--user没有配置,那么会在后面的if结构中设置SET_USER为0
# 这样在后面的判断结构中,SET_USER的值 0代表没有配置--user的值,1代表已经配置
SET_USER= # 解析配置文件中的参数,使用--loose-verbose来过滤[mysqld]和[server]组中的内容
parse_arguments `$print_defaults $defaults --loose-verbose mysqld server` if test $SET_USER -eq
then
SET_USER=
fi # 又对[safe_mysqld]和[mysqld_safe]组中的内容进行了过滤读取
# 在我的配置文件中已经没有这两个组了,估计是为兼容旧版本的需要
parse_arguments `$print_defaults $defaults --loose-verbose mysqld_safe safe_mysqld`
# 用命令行输入选项 $@ 来覆盖配置文件中的选项 机智
parse_arguments PICK-ARGS-FROM-ARGV "$@" #
# 下面是logging工具的使用
#
# 判断logger工具是否可用
if [ $want_syslog -eq ]
then
my_which logger > /dev/null >&
if [ $? -ne ]
then
log_error "--syslog requested, but no 'logger' program found. Please ensure that 'logger' is in your PATH, or do not specify the --syslog option to mysqld_safe."
exit
fi
fi # 给err_log改名字。。。
if [ -n "$err_log" -o $want_syslog -eq ]
then
if [ -n "$err_log" ]
then
# 下面是为err_log添加一个.err后缀(如果现在名字没有后缀)
# 如果不设置这个后缀,mysqld_safe和mysqld程序会将日志写入不同的文件中
# 因为在 mysqld 程序中,它将识别带有.的文件名为错误日志(脚本注释上说的) # 这里的expr是识别文件名中“.”前面的字符总数量(包括.),如果没有设置后缀,返回就是0了
if expr "$err_log" : '.*\.[^/]*$' > /dev/null
then
:
else
err_log="$err_log".err
fi case "$err_log" in
/* ) ;;
* ) err_log="$DATADIR/$err_log" ;;
esac
else
err_log=$DATADIR/`/bin/hostname`.err
fi # 追加错误日志的位置选项
append_arg_to_args "--log-error=$err_log" # 发出错误提示:不要使用syslog
if [ $want_syslog -eq 1 ]
then
log_error "Can't log to error log and syslog at the same time. Remove all --log-error configuration options for --syslog to take effect."
fi
# Log to err_log file
log_notice "Logging to '$err_log'."
logging=files # 正式把logging改成files 使用错误日志来记录日志 # 这个分支就是使用syslog的方法了
else
if [ -n "$syslog_tag" ]
then
# 设置各个syslog的使用标志位
syslog_tag=`echo "$syslog_tag" | sed -e 's/[^a-zA-Z0-9_-]/_/g'`
syslog_tag_mysqld_safe="${syslog_tag_mysqld_safe}-$syslog_tag"
syslog_tag_mysqld="${syslog_tag_mysqld}-$syslog_tag"
fi
log_notice "Logging to syslog."
logging=syslog
fi # 设置--user选项
USER_OPTION=""
if test -w / -o "$USER" = "root" # 根目录是否可写,或者当前用户为root
then
if test "$user" != "root" -o $SET_USER = 1
then
USER_OPTION="--user=$user"
fi
# 创建错误日志,并将日志授权给指定的用户
if [ $want_syslog -eq 0 ]; then
touch "$err_log"
chown $user "$err_log"
fi
# 这里它还对当前用户做了ulimit设置,包括可以打开的文件数量--open_files-limit选项
if test -n "$open_files"
then
ulimit -n $open_files
append_arg_to_args "--open-files-limit=$open_files"
fi
fi safe_mysql_unix_port={mysql_unix_port:-${MYSQL_UNIX_PORT:-/usr/local/mysql3306/tmp/mysql.sock}}
# 确保 $safe_mysql_unix_port 目录是存在的
mysql_unix_port_dir=`dirname $safe_mysql_unix_port`
if [ ! -d $mysql_unix_port_dir ]
then
mkdir $mysql_unix_port_dir
chown $user $mysql_unix_port_dir
chmod 755 $mysql_unix_port_dir
fi # 如果用户没有制定mysqld程序的名称,这里就默认赋值为mysqld
if test -z "$MYSQLD"
then
MYSQLD=mysqld
fi # 下面几段分别是对 mysqld , pid , port文件选项的检查和设置,省略100个字
if test ! -x "$ledir/$MYSQLD"
then
log_error "The file $ledir/$MYSQLD
does not exist or is not executable. Please cd to the mysql installation
directory and restart this script from there as follows:
./bin/mysqld_safe&
See http://dev.mysql.com/doc/mysql/en/mysqld-safe.html for more information"
exit 1
fi if test -z "$pid_file"
then
pid_file="$DATADIR/`/bin/hostname`.pid"
else
case "$pid_file" in
/* ) ;;
* ) pid_file="$DATADIR/$pid_file" ;;
esac
fi
append_arg_to_args "--pid-file=$pid_file" if test -n "$mysql_unix_port"
then
append_arg_to_args "--socket=$mysql_unix_port"
fi
if test -n "$mysql_tcp_port"
then
append_arg_to_args "--port=$mysql_tcp_port"
fi #
# 接下来是关于优先级的设置
# if test $niceness -eq 0
then
NOHUP_NICENESS="nohup"
else
NOHUP_NICENESS="nohup nice -$niceness"
fi # 将当前的默认优先级设置为0
if nohup nice > /dev/null 2>&1
then
# normal_niceness记载默认的调度优先级
normal_niceness=`nice`
# nohup_niceness记载使用nohup执行方式的调度优先级
nohup_niceness=`nohup nice 2>/dev/null` numeric_nice_values=1
# 这个for是为了检查$normal_niceness $nohup_niceness两个变量值的合法性
for val in $normal_niceness $nohup_niceness
do
case "$val" in
-[0-9] | -[0-9][0-9] | -[0-9][0-9][0-9] | \
[0-9] | [0-9][0-9] | [0-9][0-9][0-9] )
;;
* )
numeric_nice_values=0 ;;
esac
done # 这个判断结构很重要
# 它保证了使用nohup执行的mysqld程序在调度优先级上不会低于直接执行mysqld程序的方式
if test $numeric_nice_values -eq 1
then
nice_value_diff=`expr $nohup_niceness - $normal_niceness`
if test $? -eq 0 && test $nice_value_diff -gt 0 && \
nice --$nice_value_diff echo testing > /dev/null 2>&1
then
# 进入分支说明$nohup_niceness的值比$normal_niceness大,即nohup执行方式调度优先级比正常执行方式低
# 这是不希望看到的,所以下面就人为的提升了nohup的优先级(降低niceness的值)
niceness=`expr $niceness - $nice_value_diff`
NOHUP_NICENESS="nice -$niceness nohup"
fi
fi
else
# 下面是测试nohup在当前系统中是否可用,不可用的话就置空NOHUP_NICENESS
if nohup echo testing > /dev/null 2>&1
then
:
else
NOHUP_NICENESS=""
fi
fi # 指定内核文件大小
if test -n "$core_file_size"
then
ulimit -c $core_file_size
fi #
# 如果已经存在一个pid文件,则检查是否有已经启动的mysqld_safe进程
if test -f "$pid_file"
then
PID=`cat "$pid_file"`
if /bin/kill -0 $PID > /dev/null 2> /dev/null
then
if /bin/ps wwwp $PID | grep -v " grep" | grep -v mysqld_safe | grep -- "$MYSQLD" > /dev/null
then
log_error "A mysqld process already exists"
exit 1
fi
fi
# 下面是处理办法:删除旧的pid文件并报错
rm -f "$pid_file"
if test -f "$pid_file"
then
log_error "Fatal error: Can't remove the pid file:
$pid_file
Please remove it manually and start $0 again;
mysqld daemon not started"
exit 1
fi
fi #
# 下面便是拼接执行语句运行了。
# cmd="$NOHUP_NICENESS" # 检查一下命令 并进行转义操作
for i in "$ledir/$MYSQLD" "$defaults" "--basedir=$MY_BASEDIR_VERSION" \
"--datadir=$DATADIR" "$USER_OPTION"
do
cmd="$cmd "`shell_quote_string "$i"`
done
cmd="$cmd $args"
# Avoid 'nohup: ignoring input' warning
test -n "$NOHUP_NICENESS" && cmd="$cmd < /dev/null" log_notice "Starting $MYSQLD daemon with databases from $DATADIR" # 后台循环 执行mysqld
while true
do
rm -f $safe_mysql_unix_port "$pid_file" # 保险起见,又删除了一次pid文件 # 调用eval_log_error函数,传入$cmd参数的值,最后使用eval命令执行了启动mysqld
eval_log_error "$cmd" if test ! -f "$pid_file" # 没有成功创建pid文件,则退出分支
then
break
fi # mysqld_safe已经启动的处理方法,保证只有一个mysqld_safe程序启动
if true && test $KILL_MYSQLD -eq 1
then
# 统计启动的mysqld进程的数目
numofproces=`ps xaww | grep -v "grep" | grep "$ledir/$MYSQLD\>" | grep -c "pid-file=$pid_file"` log_notice "Number of processes running now: $numofproces"
I=1
while test "$I" -le "$numofproces"
do
# 这个PROC的数据即是ps mysqld_safe程序的输出 第一个数字即为进程ID
PROC=`ps xaww | grep "$ledir/$MYSQLD\>" | grep -v "grep" | grep "pid-file=$pid_file" | sed -n '$p'`
# 使用T来获取进程ID
for T in $PROC
do
break
done
# kill掉该个mysqld_safe程序
if kill -9 $T
then
log_error "$MYSQLD process hanging, pid $T - killed"
else
break
fi
# 每干掉一个mysqld_safe就把I加一,这样没有多余的mysqld_safe时就可以跳出循环了
I=`expr $I + 1`
done
fi
log_notice "mysqld restarted"
done # 完结撒花
log_notice "mysqld from pid file $pid_file ended"

一篇很好的关于mysqld_safe脚本源码解读的文章,收藏了!!的更多相关文章

  1. 手机3D游戏开发:自定义Joystick的相关设置和脚本源码

    Joystick在手游开发中非常常见,也就是在手机屏幕上的虚拟操纵杆,但是Unity3D自带的Joystick贴图比较原始,所以经常有使用自定义贴图的需求. 下面就来演示一下如何实现自定义JoySti ...

  2. (3.4)mysql基础深入——mysql.server启动脚本源码阅读与分析

    (3.4)mysql基础深入——mysql.server启动脚本源码阅读与分析 my.server主要分为3大部分 [1]变量初始化部分 [2]函数声明部分 [3]具体执行部分 #!/bin/sh # ...

  3. Tomcat的启停脚本源码解析

    Tomcat是一款我们平时开发过程中最常用到的Servlet容器.本系列博客会记录Tomcat的整体架构.主要组件.IO线程模型.请求在Tomcat内部的流转过程以及一些Tomcat调优的相关知识. ...

  4. 新浪微博之XSS蠕虫脚本源码讲解

    主要是因为新浪的广场页面有几个链接对输入参数过滤不严导致的反射性XSS.======================================== 微博XSS漏洞点 weibo.com/pub/ ...

  5. gradle脚本源码查看环境搭建

    背景 我刚入门学习gradle时,网上资料都是说通过gradle的api查看并学习脚本编写,但是api一般只有接口说明,并不能深入了解各个api的实现逻辑,有时就会对一些脚本的写法感到疑惑.通过搭建源 ...

  6. 《转载-两篇很好的文章整合》Android中自定义控件

    两篇很好的文章,有相互借鉴的地方,整合到一起收藏 分别转载自:http://blog.csdn.net/xu_fu/article/details/7829721 http://www.cnblogs ...

  7. C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码

    前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 一点感想 很意外的,第一 ...

  8. 两篇很好的EPG相关文章

    两篇很好的EPG相关文章 原文地址:http://blog.sina.com.cn/s/blog_53220cef0100pi8j.html 1 基于DVB-SI的数字有线电视机顶盒节目指南的设计实现 ...

  9. [Hadoop源码解读](六)MapReduce篇之MapTask类

    MapTask类继承于Task类,它最主要的方法就是run(),用来执行这个Map任务. run()首先设置一个TaskReporter并启动,然后调用JobConf的getUseNewAPI()判断 ...

随机推荐

  1. BZOJ4025: 二分图【线段树分治】【带撤销的并查集】

    Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简单的问题神犇当然会做了,于是他想考考你. Input ...

  2. Visual C#中的winform/webform/asp.net控件命名规范

                                                                            1.控件命名规范 类型 前缀 示例 AdRotator ...

  3. PHP 中的文本截取分析之效率

    PHP 中的文本截取分析之效率 在使用 ThinkPHP 或 Laravel 时都会有用到文本截取的帮助函数. 分别是 msubstr (ThinkPHP 3,ThinkPHP 5 没找到) mb_s ...

  4. Axis开发Web Service

    可以自动生成代码的 一.Axis环境的安装 1.安装环境 J2SE SDK 1.4,Tomcat 5.0,eclipse 3.2. 2.到 http://xml.apache.org 网站下载Axis ...

  5. 关于 javascript:void(0) 的问题.

    原文地址:楚广明的博客 http://www.cnblogs.com/chu888chu888/archive/2012/01/05/2313045.html 最近看了好几个关于<a>标签 ...

  6. Webpack-simple cross-env 不是内部或外部命令问题处理

    本文转载自:https://www.cnblogs.com/stono/p/6984222.html Webpack-simple cross-env 不是内部或外部命令问题处理 学习了:https: ...

  7. Java--不可覆盖的方法

    私有方法不能被覆盖: 因为private被自动认为final,对子类是屏蔽的,那么子类中的相同方法就是一个新的方法,编译器不会报错但也不会按期望运行: public class ClassA { pr ...

  8. xlrd库的使用

  9. mysql 使用inet_aton和inet_ntoa处理ip地址数据

    mysql 使用inet_aton和inet_ntoa处理ip地址数据 mysql提供了两个方法来处理ip地址 inet_aton 把ip转为无符号整型(4-8位) inet_ntoa 把整型的ip转 ...

  10. Charles使用1

    Charles是一款比较常用的全平台的网络封包街区工具,而我们在做移动开发的时候,我们为了调试.测试.分析等目的,经常需要和服务端的网络通讯协议打交道.Charles可以帮我们截取网络数据包来进行分析 ...