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();

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 );
}

SyntaxError: unexpected token: identifier

最近在处理Javascript脚本的时候,做了净化(purify)处理,然后很多文件都出现了下面的错误:

SyntaxError: unexpected token: identifier

没啥经验,发现都在一行上怎么调试呢?

就写个PHP脚本处理吧

/**
* 根据列码获取内容
* https://www.*.cn/connect-getjscolbynum-1104-100-discussimg.html
**/
function getjscolbynum( $colnum = 6647, $colnumlen = 100, $file=’page-gallery’ )
{

switch($file){
case ‘page-gallery’:
$filename = ‘https://imgoss.*.cn/public/app/b2c/statics/js_mini/page-gallery.js’;
break;
case ‘max_footer_mini’:
$filename = ‘https://imgoss.*.cn/themes/MAX360buy/images/max_footer_mini.js’;
break;
case ‘discussimg’:
$filename = ‘https://imgoss.*.cn/public/app/b2c/statics/js_mini/discuss-img.js’;
break;

}
$ffff = file_get_contents( $filename );
echo substr($ffff,$colnum,$colnumlen);
}

通过比对,发现如果涉及到匿名函数的时候,后面的分号要特别注意了,必须写上分号,要不很容易出现上面这个错误提示。

文件格式unix与dos转换,CRLF与LF的区别查看

这两天被一个客户的网站系统搞得很头痛的,开发的好好地不知道哪里错了,新建的文件都是不能正确执行的。

怎么检查代码都是不正确的,噢,文件是PHP的文件,经过调试,最终定位在凡是require_once进来的文件都是不会被初始化的。

奇怪的是,原先的程序代码是可以的,但是一旦修改了,就会出现空白的情况。

一直翻查程序文件都没问题。

终于在调试的过程不断的变换编码中发现一个问题:就是程序里面的代码会莫名其妙的成了“乱码”直接显示出来了。

好吧,引入今天的话题吧。

文件的格式虽然都叫做纯文本,但是他们的存储格式还是有不同的,比如这个文件格式就分unxi、dos、mac。

文件格式之外,存储的内容还有编码的区别,比如utf-8、ansi等的区别。

同一个编码还存在有BOM没有BOM的区别。

当然,还有CRLF与LF的区别,天呐,真的会疯了的。

我不就想要好好编个程嘛~

下面就是使用notepad++来查看这些内容的。

第一、文档格式

编辑、文档格式转换

  1. 转换为Windows格式
  2. 转换为UNIX格式
  3. 转换为MAC格式

当前的文档格式会成灰色。

VI操作:

set fileformat=[unix|dos]

这个决定下面换行符的行为模式。

第二、CRLF与LF的查看

视图、显示符号、显示全部字符

然后你会发现,全部的字符后面都增加了CRLF或者LF了,具体是根据你的文档格式来定的。

这个决定行与行之间是什么关系,比如本来应该单行注释一行,紧跟一行正确代码,然后这个不正确的话就变成了同一行了,然后文件就错了。而使用这些智能的编辑器,他显示是自动转换的,结果你是死活不知道原来他的处理已经并成一行了。

第三、存储的编码

编码、选择合适的编码

这个决定文件的字符是正常文字还是“乱码”。

这样子之后就正常了~

怎么获取手机端的页面信息

前天修改了ECSTORE商城的转向,实现根据上网终端,自动将访问地址转向正确的链接,简单的说就是给你一个PC端的链接,你用手机访问,就能自动切换到手机端的链接上。

然后,我擦就出现了今天这个问题,之前用file_get_contents获取WAP端的内容并获取手张图片的代码忽然不能工作了。

经过排查,手机端调用的时候全部都访问PC端的页面了,我擦,数据不正确是正常的。

那么,怎么处理?

下面就是增加手机端访问的代码,其实很简单的。

参考网址:php 模拟手机访问页面并抓取数据

其实就是偷懒,去那边拿了一个手机头部定义哈~感激

// 定义常用的变量
$timeout = 60;
 $url = 'http://www.shanmai.cn/wap/article-1364.html';
 $header = array(
 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4'
 ); 
 
 // 方法 1.用curl
 $ch = curl_init(); 
 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
 curl_setopt($ch, CURLOPT_URL, $url);
 $contents = curl_exec($ch);
 print_r($contents);
 
 // 方法 2.用file_get_contents
 $opts = array(
 'http'=>array(
 'method'=>'GET',
 'timeout'=>$timeout,
 'header'=>$header
 )
 );
 $cx = stream_context_create($opts);
 $contents = file_get_contents( $url, false, $cx );
 print_r($contents);

当然,还有其他方法,如fsockopen等,不过不常用就不写了。

参考链接:

 

 

ECSTORE-后台管理视图详情的翻页功能扩展

ECSTORE系统后台的管理视图是很方便我们的功能开发,唯一不足的是,如果我们的详情的内容有翻页,那么就必须在管理控制器里面写ajax_html方法,然后来调用传入的方法,生成翻页内容。

延伸:可以查看会员列表中的预存款里面的翻页,只要记录大于10项就可以看到了

可是,实际上,在finder的定义中我们已经写过一次代码了,完全没必要再写一次代码,但是,如果直接将连接指向finder内的方法的话,我们会发现,tab的表头一直再重复,很麻烦,怎么办呢?

二次开发呗~

我们的目标是:将那个表头去掉。

找到文件:

\app\desktop\lib\finder\builder\detail.php

找到行

if( count($this->detail_pages)>1){
echo $tab_header;
}

修改为下面代码:

if( count($this->detail_pages)>1 && ($_GET['noshow']==false) )
{
echo $tab_header;
}

保存。

然后,只要在翻页的地方将连接上增加&noshow=true然后就可以实现将表头去掉的功能了。

其他调用就看你自己的了咯~

2017.08.18 续

解决完这个问题后,同事有开发了一个详情页,然后按照这个逻辑操作,结果发现,tab切换的第一屏是有tab表头的,但是!当点击下一页的时候却发现表头消失了。

很诡异噢,实在没有时间检查一直拖到今天下午才检查,才发现,原来,这是一个误伤。

根本不需要重新二开呀,本来功能就是可以翻页的。

问题出在之前的同事开发的时候不知道从哪里找了一个模板,模板里面有一个开头:

<div>
<div container='true'>
...
</div>
</div>

只需要将这两行开头的去掉,问题就解决了,就不会出现重复的问题了,原因是因为加载的机制决定了这个是不能出现的,出现就会嵌套进去了。

微信-公众号网页授权信任登录开发调试

最近帮朋友增加ECSHOP商城系统的微信信任登录功能,不过他的公众号还没下来,难道不能开发?

想了一下,手上已经有一个公众号是认证的了,能不能用他来搞呢?

当然,最害怕的是会影响原先的应用。

试了一下,哈,问题解决,还没干扰。

解决办法是:

接口调用的时候需要传redirect_uri参数,而我们的公众号的微信授权登录填写的就是这个地址。

所以了,只要是redirect_uri下面的应用都是能收到授权信息的。

那就将code回传到这个redirect_uri地址,然后自己在做转发不就行了?

简单吧^_^

附上转发代码:

转发的网址比较复杂,所以使用了base64编码了~

error_reporting( E_ALL ^ E_NOTICE );
if( isset($_GET['URL']) )
{
$URL = base64_decode( $_GET['URL'] );
unset( $_GET['URL'] );
$URL .= (strpos($URL,'?')===false?'?':'&') . http_build_query( $_GET );
header( 'Location:' . $URL );
}

Fatal error: Cannot use string offset as an array in

Fatal error: Cannot use string offset as an array in /data/……/vcode.php on line 8

//...
if($_SESSION['error_count'][$app_id] >= 3) return true;
//...

其实,出现这个问题的是因为提示的这个变量($_SESSION[‘error_count’])不是数组,而却以数组的形式获取数据。

Linux系统 Nginx Apache MySQL PHP 编译参数查看命令汇总

从前人手上接过服务器的话,最烦恼的就是以前编译的参数是那些,现在可以用下面的命令直接查看了噢。

本文摘自《云服务器 ECS Linux系统 Nginx Apache MySQL PHP 编译参数查看命令汇总

查看 nginx 编译参数


  1. root@ubuntu:~# nginx -V
  2. nginx: nginx version: nginx/1.0.8
  3. nginx: built by gcc 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
  4. nginx: TLS SNI support enabled
  5. nginx: configure arguments: --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx.lock --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/body --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --with-http_stub_status_module --with-http_flv_module --with-http_ssl_module --with-http_dav_module --with-http_gzip_static_module --with-http_realip_module --with-http_sub_module --add-module=../substitutions4nginx-read-only --add-module=../ngx_cache_purge-1.4 --add-module=../ngx_http_upstream_keepalive-d9ac9ad67f45 --add-module=../agentzh-memc-nginx-module-5b0504b --add-module=../agentzh-srcache-nginx-module-10d968e

查看 apache 编译参数


  1. root@ubuntu:~# cat /usr/local/apache2/build/config.nice
  2. #! /bin/sh
  3. #
  4. # Created by configure
  5. "./configure" \
  6. "--prefix=/usr/local/apache2" \
  7. "--with-included-apr" \
  8. "--enable-so" \
  9. "--enable-deflate=shared" \
  10. "--enable-expires=shared" \
  11. "--enable-rewrite=shared" \
  12. "--enable-static-support" \
  13. "--disable-userdir" \
  14. "$@"

查看 mysql 编译参数


  1. root@ubuntu:~# find /usr -name mysqlbug
  2. /usr/bin/mysqlbug
  3. root@ubuntu:~# cat "/usr/bin/mysqlbug"|grep configure
  4. # This is set by configure
  5. CONFIGURE_LINE="../configure '--build=x86_64-linux-gnu' '--host=x86_64-linux-gnu' '--prefix=/usr' '--exec-prefix=/usr' '--libexecdir=/usr/sbin' '--datadir=/usr/share' '--localstatedir=/var/lib/mysql' '--includedir=/usr/include' '--infodir=/usr/share/info' '--mandir=/usr/share/man' '--with-server-suffix=-3ubuntu12.7' '--with-comment=(Ubuntu)' '--with-system-type=debian-linux-gnu' '--enable-shared' '--enable-static' '--enable-thread-safe-client' '--enable-assembler' '--enable-local-infile' '--with-pstack' '--with-fast-mutexes' '--with-big-tables' '--with-unix-socket-path=/var/run/mysqld/mysqld.sock' '--with-mysqld-user=mysql' '--with-libwrap' '--without-readline' '--with-ssl' '--without-docs' '--with-extra-charsets=all' '--with-plugins=max' '--without-ndbcluster' '--with-embedded-server' '--with-embedded-privilege-control' 'build_alias=x86_64-linux-gnu' 'host_alias=x86_64-linux-gnu' 'CC=gcc' 'CFLAGS=-O3 -DBIG_JOINS=1 -fno-strict-aliasing' 'LDFLAGS=-Wl,-Bsymbolic-functions' 'CPPFLAGS=' 'CXX=g++' 'CXXFLAGS=-O3 -DBIG_JOINS=1 -felide-constructors -fno-exceptions -fno-rtti -fno-strict-aliasing'"

查看 php 编译参数


  1. root@ubuntu:~# php5-fpm -i|grep configure
  2. Configure Command => './configure' '--prefix=/usr/local/php-5.3.3' '--with-config-file-path=/etc/php5' '--with-mcrypt' '--with-gettext' '--with-mysql' '--with-gd' '--with-jpeg-dir' '--with-png-dir' '--with-curl' '--with-freetype-dir' '--enable-gd-native-ttf' '--enable-mbstring' '--enable-sockets' '--enable-fpm' '--with-zlib' '--with-fpm-user=www-data' '--with-fpm-group=www-data' '--enable-xml' '--enable-bcmath' '--with-mhash'

 

rpm -qa |grep php 查看安装包的版本

Warning: http_build_query(): Parameter 1 expected to be Array or Object. Incorrect value given in …

今天,在开发微信公众号发送模板消息的时候调用ECSTORE系统的发送模块base_httpclient类。结果死活出错误,一直提示:

Warning: http_build_query(): Parameter 1 expected to be Array or Object.  Incorrect value given in /data/ECS_Site/Demo/app/base/lib/curl.php on line 31

其他时候基本上没有,没有看到错误,可能也许大概没有错误,但是增加模板调用就会出现错误,所以调试一圈发现没有涉及到相关的其他调用,完全是系统本身的调用,不知道哪里涉及到了,没时间一步步的调试了。

根据错误提示:

参数1预计的参数是数组或者对象,错误的值在…

好吧翻译的有点问题但是基本的意思我们懂啦,查看手册发现http_build_query()这个方法的参数1是:可以是数组或包含属性的对象。

那么问题就在于调用的时候不是这两类的类型。

查看错误代码所在的上下文发现,这个参数的来源可能是null类型,好吧,所以增加一个判断,问题解决。

至于会不会造成其他的错误那就不好说了噢。