分类存档: PHP

PHP 5.4 新特性

精简数组用法

//old
$num = array('one', 'two', 'three');
//new
$num = ['one', 'two', 'three'];
$num = [
    '1'=>'one',
    '2'=>'two',
    '3'=>'three'
];

数组成员访问

$name = explode(",", "David, Beckham")[0];

function test()
{
    return [
        'key'  => [ 'hello'  =>  'world' ]
    ];
}
echo  test()[ 'key' ][ 'hello' ];

Trait
Traits 是一种轻量级的方法复用。

trait cURL
{
    public function curl($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        curl_close($ch);

        return $output;
    }
}

/*
 * Twitter API Class
 */
class Twitter_API
{
    use cURL;

    public function get($url)
    {
        return json_decode($this->curl("http://api.twitter.com/".$url));
    }
}

/*
 * Facebook API Class
 */
class Facebook_API
{
    use cURL;

    public function get($url)
    {
        return json_decode($this->curl("http://graph.facebook.com/".$url));
    }
}

PHP扩展Coreseek API

Coreseek API下载地址http://www.coreseek.cn/products-install/api-list/

$ wget http://pecl.php.net/get/sphinx-1.2.0.tgz
$ tar -zxvf sphinx-1.2.0.tgz
$ cd sphinx-1.2.0
$ /usr/local/php/bin/phpize
$ ./configure --with-php-config=/usr/local/php/bin/php-config
$ make && make install
#安装PHP扩展之前需要安装libsphinxclient
#报错信息:configure: error: Cannot find libsphinxclient headers
$ cd coreseek-3.2.14/csft-3.2.14/api/libsphinxclient
$ ./configure
$ make && make install
$ /usr/local/apache2/bin/apachectl restart

Coreseek全文索引配置及使用

Coreseek 是一款中文全文检索/搜索软件…(详情请见http://www.coreseek.cn

$ wget http://www.coreseek.cn/uploads/csft/3.2/coreseek-3.2.14.tar.gz
$ tar -zxvf coreseek-3.2.14.tar.gz

#安装mmseg
$ cd mmseg-3.2.14
$ ./bootstrap    #输出的warning信息可以忽略,如果出现error则需要解决
$ ./configure --prefix=/usr/local/mmseg3
$ make && make install
$ cd ..

#安装coreseek
$ cd coreseek-3.2.14
$ ./configure --prefix=/usr/local/sphinx --with-mysql --with-mmseg-includes=/usr/local/mmseg/include/mmseg --with-mmseg-libs=/usr/local/mmseg/lib/
$ make && make install

#把字典文件和mmseg.ini配置文件拷贝到相应的目录
$ cp uni.lib /usr/local/sphinx/dict/uni.lib
$ cp mmseg.ini/usr/local/sphinx/dict/mmseg.ini

#修改配置文件mmseg.ini和csft.conf
$ vim mmseg.ini
merge_number_and_ascii=1;
number_and_ascii_joint=-;
compress_space=0;
seperate_number_ascii=1;
#merge_number_and_ascii: 字母和数字连续出现是非切分 #number_and_ascii_joint:连接数字和字母可用的符号,如'-' '.' 等
#compress_space:暂时无效
#seperate_number_ascii:是否拆分数字,如 1988 -> 1/x 9/x 8/x 8/

$ vim csft.conf
source src1
{
        type = mysql  

        sql_host = localhost
        sql_user = root
        sql_pass = 123456
        sql_db = dbTest
        sql_port = 3306  # optional, default is 3306  

        sql_query = select id, content, addtime, reason, flag from tbLog  

        sql_attr_uint = id
        sql_attr_timestamp = addtime

        sql_query_info = SELECT * FROM tbLog WHERE id=$id
}

index test1
{
        source = src1
        path = /data/sphinx/data
        docinfo = extern
        charset_type = sbcs
        charset_dictpath = /usr/local/sphinx/dict
}  

indexer
{
        mem_limit = 32M
}  

searchd
{
        port = 9312
        log = /data/sphinx/log/searchd.log
        query_log = /data/sphinx/log/query.log
        read_timeout = 5
        max_children = 30
        pid_file = /data/sphinx/log/searchd.pid
        max_matches = 1000
        seamless_rotate = 1
        preopen_indexes = 0
        unlink_old = 1
}

#生成index
$ /usr/local/sphinx/bin/indexer --config /usr/local/sphinx/etc/csft.conf --all

#启动daemon
$ /usr/local/sphinx/bin/searchd --config /usr/local/sphinx/etc/csft.conf

#关闭服务
$ /usr/local/sphinx/bin/searchd --config /usr/local/sphinx/etc/csft.conf --stop

#启动之后如果更新索引要加rotate参数
#/usr/local/sphinx/bin/indexer --config /usr/local/sphinx/etc/csft.conf --all --rotate

#测试
$ /usr/local/sphinx/bin/search 'test'

为phpMyAdmin 增加安全口令

由于phpMyAdmin没有设置口令,任何人都可以控制数据库,所以增加一个安全口令,提高安全性。

$ vim /usr/local/apache2/conf/http.conf
#增加以下配置
<Directory "/var/www/html/phpMyAdmin">
    Options Includes FollowSymLinks
    AllowOverride all
    Allow from all
        AuthName "Administrator Auth"
        AuthType Basic
        AuthUserFile /etc/superzc.pwd
        require valid-user
    Order allow,deny
</Directory>
#增加用户以及密码
$ /usr/local/apache2/bin/htpasswd -c /etc/superzc.pwd superzc
password:  #输入安全口令的密码
$ /usr/local/apache2/bin/apachectl restart

重启apache之后,访问phpMyAdmin,搞定~已经需要安全验证。

Xdebug 安装与应用

之前,一直在用Xdebug,但是自己还没有尝试过安装,也没尝试过对Xdebug的应用提升,今天正好有空尝试了下。

Xdebug:是一个开放源代码的PHP程序调试器(即一个Debug工具),可以用来跟踪,调试和分析PHP程序的运行状况。

安装:

$ wget http://xdebug.org/files/xdebug-2.1.3.tgz
$ tar -zxvf xdebug-2.1.3.tgz
$ cd xdebug-2.1.3/
$ /usr/local/php/bin/phpize
$ ./configure --enable-xdebug --with-php-config=/usr/local/php/bin/php-config
$ make
$ make install
$ cd /usr/local/php/lib
$ vim php.ini
[Xdebug]
extension="xdebug.so"
xdebug.auto_trace=0
xdebug.collect_params=4
xdebug.collect_return=on
xdebug.show_mem_delta=1  #查看内存使用量
xdebug.profiler_enable=0  #只对指定的页面调试,和‍xdebug.profiler_enable_trigger连用
xdebug.profiler_output_dir="/tmp/"
xdebug.profiler_enable_trigger=1  #通过XDEBUG_PROFILE的get/post请求触发页面调试
$ /usr/local/apache2/bin/apachectl restart

安装成功后,显示如下截图:

应用

随便写了个php,测试下报错信息是否已经是应用Xdebug,截图如下:

应用提升:

register_shutdown_function('xdebug_stop_trace');

xdebug_start_trace("/tmp/xLog_test");

/*此处省略过程代码*/

xdebug_stop_trace();

生成的Xdebug日志文件/tmp/xLog_test.xt,部分内容截图如下:

通过Xdebug的日志,我们可以了解到时间和内存的使用情况,也可以了解陌生产品架构的方式,还可以通过执行时间快速的定位问题。

运用WinCacheGrind.exe:
1.WinCacheGrind.exe,下载地址:http://sourceforge.net/projects/wincachegrind/
2.如果xdebug.profiler_enable_trigger = 1开启状态,可以用游览器+调试参数XDEBUG_PROFILE来生成cachegrind.out.xxxx的文件,比如用游览器访问:http://www.superzc.com/index.php?id=1&XDEBUG_PROFILE。然后在xdebug.profiler_output_dir=”/tmp/”设置的目录下就生成了一个cachegrind.out.xxxx的文件;
3.最后用WinCacheGrind来解读这个文件,点击菜单栏的”File” –> “Open…”,选择cachegrind.out.xxxx文件,然后打开,如下图:

PHP APC 安装与应用

APC:Alternative PHP Cache (APC)是一种对PHP有效的开放源高速缓冲储存器工具,他能够缓存opcode的php中间码。

PHP APC提供两种缓存功能,即缓存Opcode(目标文件),我们称之为apc_compiler_cache。同时它还提供一些接口用于PHP开发人员将用户数据驻留在内存中,我们称之为apc_user_cache。

安装:

$ wget http://pecl.php.net/get/APC-3.1.9.tgz
$ tar -zxvf APC-3.1.9.tgz
$ cd APC-3.1.9/
$ /usr/local/php/bin/phpize
$ ./configure --enable-apc --enable-mmap --enable-apc-spinlocks --disable-apc-pthreadmutex --with-php-config=/usr/local/php/bin/php-config
$ make
$ make install
$ vim php.ini
#增加以下APC配置
[apc]
extension="apc.so"
apc.enabled=1
apc.cache_by_default=on  #对所有文件启用缓冲
apc.shm_segments=1  #apc.shm_segments指定了使用共享内存块数
apc.shm_size=64  #apc.shm_size指定一块共享内存空间大小,单位是M
apc.ttl=7200  #缓存条目在缓冲区中允许逗留的秒数
apc.user_ttl=7200
apc.num_files_hint=0
apc.write_lock=on  #启用写入锁
$ cd /home/super/APC-3.1.9/
$ cp apc.php /var/www/html/
$ /usr/local/apache2/bin/apachectl restart

调用phpinfo(),安装完成了,显示如下图:

访问apc.php,显示如下图:

PS:APC提供了apc.php,用于监控与管理APC缓存。不要忘记修改管理员名和密码:

defaults('ADMIN_USERNAME','super');
defaults('ADMIN_PASSWORD','123456');

应用:
1.函数说明:
apc_clear_cache() 清除apc缓存内容
默认(无参数)时,只清除系统缓存,要清除用户缓存,需用’user’参数

apc_define_constants ( string key, array constants [, bool case_sensitive] )
将数组constants以常量加入缓存

apc_load_constants (string Key)
取出常量缓存

apc_store ( string key, mixed var [, int ttl] )
在缓存中保存数据

apc_fetch ( string key )
获得apc_store保存的缓存内容

apc_delete ( string key )
删除apc_store保存的内容

<?php
$test=array(
'abc'=>'super',
'def'=>'hello world'
);

apc_define_constants('test_const',$test);

apc_load_constants('test_const');

echo 'test_const:'.abc;  //注意abc前面没有$
?>

输出:test_const:super

<?php
$bar = 'BAR';
apc_store('foo', $bar);
var_dump(apc_fetch('foo'));
?>

启动apache 报错:libphp5.so:undefined symbol: zend_parse_parameters

今天在PHP扩展ssh2的时候,重启apache时候,发现报错,网上找了好久资料,一种是关闭selinux,怕安全性问题没这么做,后来又找到了一个解决方案(http://www.linuxforums.org/forum/red-hat-fedora-linux/87975-configuring-php-work-apache.html),如下:

$ /usr/local/apache2/bin/apachectl start
httpd: Syntax error on line 203 of /etc/httpd/conf/httpd.conf: Cannot load /usr/lib/httpd/modules/libphp5.so into server: /usr/lib/httpd/modules/libphp5.so: undefined symbol: zend_parse_parameters

解决方法:
首先,安装bison,bison 是替代yacc的语法分析程序生成器。

$ wget http://ftp.gnu.org/gnu/bison/bison-2.5.tar.gz
$ tar -zxvf bison-2.5.tar.gz
$ cd bison-2.5
$ ./configure
$ make
$ make install

然后,重新编译php

$ make install distclean
$ /usr/local/apache2/bin/apachectl start

[转]利用php调用C语言 扩展函数

第一步. 生成需要调用的so文件

1. 首先做一个简单的so文件:

/** * hello.c
* To compile, use following commands:
*   gcc -O -c -fPIC -o hello.o hello.c
*   gcc -shared -o libhello.so hello.o
*/
int hello_add(int a, int b)
{
return a + b;
}

然后将它编译成.so文件并放到系统中:

$ gcc -O -c -fPIC -o hello.o hello.c #-fPIC:是指生成的动态库与位置无关;假如是c++程序,用g++  -O -c -fPIC -o hello.o hello.c
$ gcc -shared -o libhello.so hello.o #-shared:是指明生成动态链接库;假如需要编译多个文件:g++ a.h b.cpp -fPIC -shared -o libtest.so
$ cp libhello.so /usr/local/lib #把生成的链接库放到指定的地址
$ echo /usr/local/lib > /etc/ld.so.conf.d/local.conf #把库地址写入到配置文件中
$ /sbin/ldconfig #用此命令,使刚才写的配置文件生效

2. 写段小程序来验证其正确性:

/**
* hellotest.c
* To compile, use following commands:
*   gcc -o hellotest -lhello hellotest.c
*/
#include <stdio.h>
int main()
{
int a = 3, b = 4;
printf("%d + %d = %d", a, b, hello_add(a,b));
return 0;
}

编译并执行:

$ gcc -o hellotest -lhello hellotest.c #编译测试文件,生成测试程序
$ ./hellotest #运行测试程序

第二步. 制作PHP模块(外部模块)

请确保你已安装 PHP及APACHE服务器。

$ cd php-5.2.3/ext

1. 然后通过下面的命令用ext_skel脚本建立一个名为 hello 的模块:

$ ./ext_skel --extname=hello

2. 执行该命令之后它会提示你应当用什么命令来编译模块,可惜那是将模块集成到php内部的编译方法。

如果要编译成可动态加载的 php_hello.so,方法要更为简单。

$ cd hello

首先编辑 config.m4 文件,去掉第16行和第18行的注释(注释符号为 dnl 。)

16: PHP_ARG_ENABLE(hello, whether to enable hello support,

17: dnl Make sure that the comment is aligned:

18: [ --enable-hello Enable hello support])

3. 然后执行 phpize 程序,生成configure脚本:

$ phpize

该程序在ubuntu的php5-dev包中

4. 打开 php_hello.h,在 PHP_FUNCTION(confirm_hello_compiled); 之下加入函数声明:

PHP_FUNCTION(confirm_hello_compiled); /* For testing, remove later. */

PHP_FUNCTION(hello_add);

5. 打开 hello.c,在 PHP_FE(confirm_hello_compiled, NULL) 下方加入以下内容。

zend_function_entry hello_functions[] = {

PHP_FE(confirm_hello_compiled, NULL) /* For testing, remove later. */

PHP_FE(hello_add, NULL) /* For testing, remove later. */

{NULL, NULL, NULL} /* Must be the last line in hello_functions[] */};

然后在 hello.c 的最末尾书写hello_add函数的内容:

PHP_FUNCTION(hello_add)

{

long int a, b;

long int result;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, “ll”, &a, &b) == FAILURE) {

return;

}

result = hello_add(a, b);

RETURN_LONG(result);}保存退出,编译并安装。

表: zend_parse_parameters() 字母对应的类型

类型 字母 变量类型
Boolean b zend_bool
Long l long
Double d double
String s char *, int
Resource r zval *
Array a zval *
Object o zval*
zval z zval*

6. 编译

$ ./configure
#此处由于php-config的路径问题报错,解决方法:./configure --with-php-config=/usr/local/php/bin/php-config
$ make LDFLAGS=-lhello
$ sudo make install #编译生成了php扩展模块
Installing shared extensions: /usr/lib/php5/20060613
$ cp modules/hello.so /usr/lib/php/modules
$ vim /usr/local/php/lib/php.ini
#enable_dl = Off;允许dl()动态加载so扩展功能enable_dl = On
#增加一条:extension=hello.so
$ /usr/local/apache2/bin/apachectl restart

然后在 /var/www/html 下建立一个 hello.php 文件,内容如下:

<?php
dl("hello.so");
echo hello_add(3, 4);
?>

然后在浏览器中打开hello.php文件,如果显示7,则说明函数调用成功了。

第三步. 制作PHP模块(内部模块)

另外可以在apache重启的时候让我们的so库直接动态编译进php5,就像linux的insmod hello.ko模块一样,不用dl加载也不用重新编译php,就可以直接使用so的函数了,步骤如下:

$ vim /etc/php5/apache2/php.ini
#enable_dl = Off
#增加一条:extension=hello.so
$ /usr/local/apache2/bin/apachectl restart

不能reload而必须restart apache,这样so就像insmod hello.ko一样被融到了php5内核,然后代码就可以忽略掉dl(“hello.so”);了,
[注意,这种方式只适合hello.so库内所有功能代码已经全部调试ok,如果还处在调试期间,那么需要采用上面的dl强制加载的方式]

代码如下:

<?php
echo hello_add(3, 4);
?>

但是该功能不太适合调试,因为每次修改hello.so中代码的话,都需要让service apache restart重启才能让php5内核再次加载新的hello.so扩展.可以这样定义hello.so的实现,这样每次执行.php网页,都会在 /var/www/下建立一个文件夹,所以php扩展实现了

HTTP 协议

HTTP 304

304 的标准解释是:Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。

如果客户端在请求一个文件的时候,发现自己缓存的文件有 Last Modified ,那么在请求中会包含 If Modified Since ,这个时间就是缓存文件的 Last Modified 。因此,如果请求中包含 If Modified Since,就说明已经有缓存在客户端。只要判断这个时间和当前请求的文件的修改时间就可以确定是返回 304 还是 200 。对于静态文件,例如:CSS、图片,服务器会自动完成 Last Modified 和 If Modified Since 的比较,完成缓存或者更新。但是对于动态页面,就是动态产生的页面,往往没有包含 Last Modified 信息,这样浏览器、网关等都不会做缓存,也就是在每次请求的时候都完成一个 200 的请求。

因此,对于动态页面做缓存加速,首先要在 Response 的 HTTP Header 中增加 Last Modified 定义,其次根据 Request 中的 If Modified Since 和被请求内容的更新时间来返回 200 或者 304 。虽然在返回 304 的时候已经做了一次数据库查询,但是可以避免接下来更多的数据库查询,并且没有返回页面内容而只是一个 HTTP Header,从而大大的降低带宽的消耗,对于用户的感觉也是提高。

当这些缓存有效的时候,查看一个请求会得到这样的结果:

第一次访问 200

鼠标点击二次访问 (Cache)

按F5刷新 304

按Ctrl+F5强制刷新 200

HTTP 3xx

301 Moved Permanently:请求的资源已经被赋予一个新的URL

header( "HTTP/1.1 301 Moved Permanently" ) ;
header( "Location:http://www.superzc.com" );

304 Not Modified:如果客户端已经完成一个有条件的请求并且是允许的,但是这个文档并没有改变,服务器应该返回304状态码。304状态码一定不能包含信息主体,从而通常通过一个头字段后的第一个空行结束

HTTP 4xx:客户端错误

400 Bad Request:因为错误的语法导致服务器无法理解请求信息
403 Forbidden:服务器接收请求,但是被拒绝处理
404 Not Found

HTTP 5xx:服务器错误

500 Internal Server Error:服务器遭遇异常阻止了当前请求的执行
502 Bad Gateway

imagemagick 图片格式转换、降低图片质量、等比缩放和居中补白

图片格式转换、降低图片质量:

#-quality 70: 把图片的质量压缩到70%
$ convert test.png -quality 70 test.jpg

等比缩放:

$this->convert_cmd="/usr/bin/convert";

$size = "80x80";//图片尺寸

//源图片:$image;等比缩放后图片:$tmp_img
exec("{$this->convert_cmd} -resize $size '$image' '$tmp_img'");

居中补白:
服务器端需要安装最新的imagemagick:http://www.imagemagick.org/script/install-source.php#unix

$this->convert_cmd="/usr/bin/convert";

$size = "80x80";//图片尺寸

//源图片:$image;补白后图片:$tmp_img
exec("{$this->convert_cmd} -resize $size -background white -gravity center -extent $size '$image' '$tmp_img'");
第 1 页,共 2 页12