奇怪的特殊符号造成PHP代码执行失败

昨天不知道从哪里偷了一段代码,然后一直执行不过,一直报语法错误。

经过一个个的排查,发现是因为没行末尾都有两个字符,用ord转换后而已发现他们的原型:

echo ord( ‘ ‘ );//32
echo ord( ‘ ‘ );//194

是空格跟特殊控制符。具体看《ASCII》。

空格符明显是不能造成问题的,直接排除,然后将194这个符号增加到随便一行代码,比如加上前面ord代码上吧:

echo ord( ‘ ‘ ); //32

注意,这次//32前面有一个符号噢。然后执行就报错了,错误如下:

syntax error, unexpected ‘echo’ (T_ECHO)

嗯,问题重现,就是他造成的。

Linux-find与grep

linux中的查找搜索功能对应两个命令:find与grep。

  • find负责查找文件
  • grep负责搜索内容

他俩除了功能区别之外,对我来讲最大的不同或者叫做混乱是他们的操作目标的参数位置不一样。

啥意思?

就是find的操作对象是第一个参数,而grep的操作对象是第三个参数或者更往后。

find 所在查找目录 -option [-print] [-exec -ok command] {} \;
grep 查找内容 [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>][-d<进行动作>][-e<范本样式>][-f<范本文件>][--help][范本样式][文件或目录...]

记录一下,省的每次都要回想一下。

find / -name abc.php

find / -name *.php

# 查找修改时间为15天之前的文件并删除
# 24*60=1440 1440*15=21600分钟
find / -mmin +21600 -type f -print -exec rm -rf {} \;

# 删除2天前的文件
find / -amin +2880 -type f -print -exec rm -rf {} \;

grep “php” /

ps -ef | grep nginx

PHP-phpmyadmin的配置与使用

官方使用手册
https://docs.phpmyadmin.net/zh_CN/latest/

最近新安装了LNMP环境,安装了phpmyadmin后发现登录后会找不到网址的问题,查看一下链接发现,自动转向错了,难道要改代码?

查一下手册,发现提供一个配置项哈。

$cfg[‘PmaAbsoluteUri’] = $_SERVER[‘REQUEST_SCHEME’].’://’.$_SERVER[‘HTTP_HOST’].’/phpmyadmin’;

将这个配置项设置为绝对的URL就行。结尾不要有/或者其他的。

Linux-Redis : No rule to make target ‘release.h’, needed by ‘release.o’

最近公司开发的游戏,本地需要搭建环境,然后复制了一份从服务器拷贝来redis源码一直编译不过去(最后去官方站下载新版的覆盖也是没用的),老是出现如下提示:

No rule to make target ‘release.h’, needed by ‘release.o’.  Stop

经过辛苦的查找,才在《Redis编译问题》中找到解决方法,收藏一下,感激,其他文章基本都是扯淡~用不到。

解决方法就是给src/mkreleasehdr.sh脚本授权。

chmod 777 mkreleasehdr.sh

ecstore-短信忽然发送不了了

周一,客服反馈商城的注册短信收不到。

检查了一下发现确定发送不了,但是代码都没改,怎么会这样子呢?第一个感觉就是会不会是通道的问题。

所以上网问同样用平台的人,答案是可以发送的。

那么问题就是我们自己的问题了。

所以,写个测试例子调试吧。

随便在控制器写个调用吧,代码如下:

$messengerModel = kernel::single('b2c_mdl_member_messenger');
$mobile = '15959******';
$tmpl = 'account-lostPw';
$data = array(
	'vcode'         => time(),
);
$sendType = 'notice';
$sender = 'b2c_messenger_sms';
$tmpl_name = 'messenger:b2c_messenger_sms/'.$tmpl;
$messengerModel->_send($sender,$tmpl_name,$mobile,$data,$tmpl,$sendType);
exit('OK...');

因为这个调用时没有反馈的,我们需要在调用的时候将通道反馈的信息打印出来,需要做些调试方式。具体就根据个人的喜欢调试吧。

最终,得到结果是短信通道的密码错误。

汗~

确定没有改呀。算了,重置吧。

然后,需要使用“清除系统中原有的与shopex用户中心关联的数据”来清除关联数据。

看这个名字有点怕怕,最后新建一个新站测试发现是没问题的,仅仅是清除关联激活的信息,其他的数据完整保留哈。

这个数据就是:全新安装ecstore后会出现要激活的账号跟密码,是免费注册的一个账号。激活了才会进入后台管理界面。

下面附上调试过程中的一些重点文件,记录一下,省的以后还要重新跟。

在app\b2c\lib\messenger\sms.php中的send($to,$title,$message,$config)方法是短信发送的封装方法,自动添加签名等信息。

在app\b2c\lib\messenger\smschg.php中的send($contents,$config,&$msg)方法是主要方法,这边就是最终的调用短信通道接口的所在,所以,需要返回接口的错误信息,需要在这边调试输出。

在app\base\lib\enterprise.php中的方法关系到账户密码的获取方法。而这些数据是保存在表sdb_base_setting中,获取的SQL语句是:

SELECT * FROM `sdb_base_setting` WHERE `key` LIKE ‘ecos.enterprise_info’

我直接将加密串更新进去,然后,测试就可以了。

END

 

PHP-memcached与redis客户端测试

今天又开一台云主机,然后又要设置一下redis与memcached的有效性,哎,每次都要重复这个步骤,记录一下测试代码吧,方便查找。

// REDIS
$redis = new Redis();
$redis->connect( 'r-*.redis.rds.aliyuncs.com', 6379 );
$redis->auth( '******' );
$ret = $redis->set('www.ipodmp.com', 'ChinaBUG');
var_dump($ret);
$allKeys = $redis->keys('*');
print_r($allKeys);
$redis->close();

echo "\n",'*-***********************',"\n";

// memcached
$connect = new Memcached;
$connect->setOption(Memcached::OPT_COMPRESSION, false); //关闭压缩功能
$connect->setOption(Memcached::OPT_BINARY_PROTOCOL, true); //使用binary二进制协议
$connect->setOption(Memcached::OPT_TCP_NODELAY, true); //重要,php memcached有个bug,当get的值不存在,有固定40ms延迟,开启这个参数,可以避免这个bug
$connect->addServer('m-*.memcache.rds.aliyuncs.com', 11211); //添加OCS实例地址及端口号
$connect->setSaslAuthData('aaaaaaaaaa', '******'); //设置OCS帐号密码进行鉴权,如已开启免密码功能,则无需此步骤;新版OCS的username可以置空
$connect->set("ChinaBUG", "ChinaBUG20180809");
echo 'ChinaBUG\'s: ',$connect->get("ChinaBUG");
$connect->quit();

SHELL-自动修改文件的所有者

最近,前端同仁反馈,模板目录经常性提示没有权限修改文件,经检查是里面的文件的所有人变了,具体为什么变,暂时没找到,那就弄个脚本让他们执行修改吧。

传入的参数是要修改的目录,必须是/data/Site/下的任意目录,其他的程序排除了。

提示:

这个脚本有权限的,chown需要管理员权限,而正常部署的账号是www结果是可以执行,但没有效果噢。

#!/bin/bash

checkroot="$1"
hasexist=$(echo $checkroot | grep "/data/Site/")
if [[ (${#checkroot} -gt 0) && ($hasexist!="") ]];
then
find $checkroot -type f -user root -exec chown www:www {} \;
fi

 

SHELL-常用的功能脚本

最近,大量测试虚拟机,结果安装复制很麻烦的,特别有时候需要重新配置常用项的内容。还是写一个脚本自动完成吧。

错误提示:

如果执行的时候出现“-bash: ./ecs.sh: /bin/bash^M: bad interpreter: No such file or directory”错误则将文件的格式保存为unix格式试试看。

目前有的功能:

  1. 网卡配置生成
  2. YUM 阿里云镜像
  3. 虚拟机 共享软件夹

源码如下

#!/bin/bash

if [ $(id -u) != "0" ]; then
    echo "You must be root to run this script"
    exit 1
fi

# 网卡配置生成
eth_generate()
{
	while true
	do
		read -p "please input network card's name:" eth_input_name
		read -p "please input network card's IP ADDR:" eth_input_ipaddr
		read -p "please input network card's Gate WAY:" eth_input_gateway
		if [[ ${#eth_input_name} -gt 0 && ${#eth_input_ipaddr} -gt 0 && ${#eth_input_gateway} -gt 0 ]];
		then
			break
		else
			echo '******'
		fi
	done
	ethconfig="/etc/sysconfig/network-scripts/ifcfg-$eth_input_name"
	if [ -e /etc/sysconfig/network-scripts/ifcfg-$eth_input_name ];
	then
		mv $ethconfig $ethconfig.bak.$(date +"%Y%m%d")
	fi
	echo "TYPE=Ethernet
BOOTPROTO=static
NAME=$eth_input_name
DEVICE=$eth_input_name
ONBOOT=yes
IPADDR=$eth_input_ipaddr
GATEWAY=$eth_input_gateway">>$ethconfig
	if [ -e $ethconfig ];
	then
		echo '##### config generate OK~! #####'
	fi
	service network restart
	mv /etc/resolv.conf /etc/resolv.conf.bak.$(date +"%Y%m%d")
	echo "nameserver 223.5.5.5
nameserver 223.6.6.6">>/etc/resolv.conf
	exit 1
}

# YUM 阿里云镜像
yum_source_aliyun()
{
	if grep -Eqi "release 6." /etc/redhat-release; then
		centosver='6'
	elif grep -Eqi "release 7." /etc/redhat-release; then
		centosver='7'
	fi
	if [[ centosver -eq 6 || centosver -eq 7 ]];
	then
		mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak.$(date +"%Y%m%d")
		curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-$centosver.repo
		echo '##### CentOS-Base.repo is download OK~! #####'
		yum makecache
		echo '##### CentOS-Base.repo CACHE is OK~! #####'
	fi
	exit 1
}

# 虚拟机 共享软件夹
# 1.执行之前请点击 设备 安装增强工具
# 2.设置 共享文件夹 设定 共享文件夹名称,脚本将用到
vbox_sharefloder()
{
	# 0
	echo '1.执行之前请点击 设备 安装增强工具'
	echo '2.设置 共享文件夹 设定 共享文件夹名称,脚本将用到'
	read -p "你是否已经准备好了?准备好请输入yes回车。" isok
	if [ "$isok" != "yes" ];
	then
		echo '请前往设置后再来尝试。'
		exit 1
	fi
	# 1
	read -p "请输入共享文件夹名称: " sharefoldername
	if [[ ${#sharefoldername} -le 0 ]];
	then
		echo "共享文件夹名称 必填"
		exit 1
	fi
	read -p "请输入您希望挂载到的目录,默认/data: " mountto
	if [ ${#mountto} -le 0 ];
	then
		mountto='/data'
	fi
	# 2
	yum install kernel-headers kernel-devel gcc* make -y
	if [ ! -e /mnt/cdrom ];
	then
		mkdir -p /mnt/cdrom
	fi
	# 3
	mount /dev/cdrom /mnt/cdrom
	cd /mnt/cdrom
	./VBoxLinuxAdditions.run
	# umount /mnt/cdrom
	# 4
	if [ ! -e $mountto ];
	then
		mkdir -p $mountto
	fi
	mount -t vboxsf $sharefoldername $mountto
	# 5
	cp /etc/fstab /etc/fstab.bak.$(date +"%Y%m%d")
	echo $sharefoldername $mountto vboxsf rw,gid=100,uid=1000,auto 0 0 >> /etc/fstab
}


#
SelectTo="$1"

#
echo "1: Auto generate network card config(as ifcfg-eth0)"
echo "2: YUM source mirror from aliyun"
echo "3: Visual Box's Tool set"
echo "0: DO NOTHING"

#
if [ ${#SelectTo} -le 0 ];
then
	read -p "Choice One To Setup (1,2,3 or 0): " SelectTo
fi

#
echo '-----';

case "${SelectTo}" in
1)
	eth_generate
	;;
2)
	yum_source_aliyun
	;;
3)
	vbox_sharefloder
	;;
0)
	exit 1
	;;
*)
	echo "you can run :$0 [1|2|3...]"
	exit 1
esac

PHP中将HTML的行内样式抽离为内嵌样式或者外联样式

<?php

/**
* 说明:
* 最近为了优化页面容量,需要将内嵌,行内样式,脚本等抽离成外联调用方式,一个个检查明显是
* 工作量浩大,花了一个下午时间写个脚本自动检查,配合使用。
*
* 功能:将行内样式抽离成内嵌样式,自动重命名元素的样式名
**/
function extractionInlineStyle( $url = 'http://www.163.com/' )
{
$content = file_get_contents( $url );

// 1.将行内样式抽离出来
preg_match_all( '/style=(\"|\')?([^\"\']*)(\"|\')?/', $content, $matchs );
// 1.1.去掉空格,md5生成类名
// 1.2.删除原码,替换类名
$styleStrings = '<style>';
//
$classCountNum = 1;
foreach( $matchs[0] as $stylekey=>$styleitem )
{
$styleNameMd5[ $stylekey ] = md5( $styleitem );
$styleNameID[ $stylekey ] = 'c_'.$classCountNum;
if( !isset($styleItems[ $styleNameMd5[ $stylekey ] ]) )
{
$styleItems[ $styleNameMd5[ $stylekey ] ] = $styleNameID[ $stylekey ];
$styleName[ $stylekey ] = "class={$matchs[1][$stylekey]}{$styleNameID[ $stylekey ]}{$matchs[3][$stylekey]}";
$styleStrings .= '.'.$styleNameID[ $stylekey ].'{'.str_ireplace(array("\r","\n"),'',$matchs[2][$stylekey]).'}';
$classCountNum++;
}else{
$styleName[ $stylekey ] = "class={$matchs[1][$stylekey]}{$styleItems[ $styleNameMd5[ $stylekey ] ]}{$matchs[3][$stylekey]}";
}
}
//
$styleStrings .= '</style>';
$styleStrings = preg_replace( '/\s\s+/', '', $styleStrings );
$content = str_ireplace( '</head>', $styleStrings."\n".'</head>', $content );
$content = str_ireplace( $matchs[0], $styleName, $content );

// 2.处理重复的class属性,只能处理class X 2的
// 2.1 将重复的第二个class删除
// 2.2 将重复的class内的值合并到第一个class中
preg_match_all( '/<([^>]*)class=(?<pclass1>(\"|\')(?<pclass11>([^\"\']*))(\"|\'))([^>]*)(?<=class)=(?<pclass2>(\"|\')(?<pclass22>([^\"\']*))(\"|\'))([^>]*)>/', $content, $matchsClass );
$strRepl = $matchsClass[0];
foreach( $strRepl as $sFkey=>$sFval )
{
$find = array(
0=>' class='.$matchsClass['pclass2'][$sFkey],
1=>' class='.$matchsClass['pclass1'][$sFkey],
);
$repl = array(
0=>'',
1=>' class="'.$matchsClass['pclass11'][$sFkey].' '.$matchsClass['pclass22'][$sFkey].'"'
);
$strRepl[ $sFkey ] = str_ireplace( $find, $repl, $sFval );
}
//
$content = str_ireplace( $matchsClass[0], $strRepl, $content );

exit( $content );
}