分类目录归档:php

php中使用RabbitMq消息队列

1.RabbitMQ 是一个在AMQP基础上完成的,可复用的企业消息系统。消息队列中间件,支持多种语言,以及跨语言消息传递,安装配置文档请参照官网说明;

2. php中如何使用RabbitMQ呢?

2.1 安装php-amqp扩展,下载地址: http://pecl.php.net/package/amqp下载解压后文件如下图:将php_amqp.dll文件添加到php  ext扩展目录中并追加到php.ini文件中

2.2 使用的服务器为apache  需要将httpd.conf中添加一行 LoadFile  “rabbitmq.1.dll安装路径”;

2.3 重启apache,并查看phpinfo信息。只要看到amqp 字样即表示安装成功;

2.4 使用php-amqplib库来实现RabbitMQ消息队列的使用,使用composer 安装:composer.json 文件中require节点找那个添加 “php-amqplib/php-amqplib”:”>=2.6.1″

并执行composer update操作,或使用composer命令   composer require php-amqplib/php-amqplib来安装这个库。

2.5 可以参考github中的代码来实现具体需求 demo地址:https://github.com/php-amqplib/php-amqplib/tree/master/demo,下图两个demo为最基本的消息获取、应答和发送功能

debris

1.apache xSendFile支持

在我们提供文件下载、图片展示功能时,可能需要让php进行条件判断后(比如权限判断、扣除下载点数等),再循环读文件进行传输。这样做小文件还好,当遇到大文件时就会占用较多的内存资源,同时减慢了文件的传输速度。这个时候就需要xsendfile特性了,通过header发送xsendfile标记,可以直接把需要传输的文件直接交给web服务处理,大大减少了后台语言的资源占用,也加快了传输速度。

Ubuntu 安装xSendFile   sudo apt-get install libapache2-mod-xsendfile

xsendfile默认是关闭状态的,需要在virtual host(配置虚拟机的地方)添加两条指令

XSendFile on
XSendFilePath d:/xampp/file_path

xsendfilepath是必须配置的,因为如果不配置的话,php脚本只能调用当前及子目录的文件

脚本添加 header(‘X-Sendfile: filename.jpg’);

2.使用fsockopen实现异步调用方法

function post_socket()
{
    $fp = fsockopen("www.wenjunting.com", 80, $errno, $errstr, 30);
    if (!$fp) {
        echo "$errstr ($errno)<br />\n";
    } else {
        $arr = array('key'=>1,'name'=>'test');
        $encodeData = http_build_query($arr);

        $out = "POST /test.php HTTP/1.1\r\n";
        $out .= "Host: www.wenjunting.com \r\n";
        $out .= "Content-type: application/x-www-form-urlencoded\r\n";
        $out .= "Content-Length: ".strlen(trim($encodeData ))."\r\n";
        $out .= "Connection: Close\r\n\r\n";
        $out .= trim($data);
        fwrite($fp, $out);
       //忽略执行结果
      /* while (!feof($fp)) {
          echo fgets($fp, 128).'<br/>';
      }*/
      fclose($fp);
   }
}
更多异步方法

3.批量关闭Linux进程
 ps -ef|grep php|grep -v grep|awk '{print $2}'|xargs kill -INT  //xargs 将标准输出作为kill命令的参数


PHP7.0.19 连接SQL Server2005

  1. php.ini 需要开启扩展,但php自带扩展库中没有该数据库的扩展,就需要在微软下载,

下载地址: https://www.microsoft.com/en-us/download/details.aspx?id=20098 下载SQLSRV40.EXE

2. 解压得到php7各版本的dll动态扩展库,选择适合自己版本的放在php安装目录下的ext目录下

3. 修改php.ini 文件我这里是php7非线程安全的 :

extension=php_sqlsrv_7_nts_x64.dll

extension=php_pdo_sqlsrv_7_nts_x64.dll

4 .安装ODBC Driver 11 For SQL (msodbcsql.msi),安装时选中 ODBC Driver for SQL Server SDK安装,

下载地址:https://www.microsoft.com/en-us/download/details.aspx?id=36434

5. 重启服务器或fastcgi

6. 打印phpinfo页面,查看pdo/pdo_sqlsrv/扩展是否开启

7. 如果开启了,使用pdo连接下数据库,如果还显示驱动不存在,再去配置数据库

数据库连接实例请参照php官网

8. SQL Server配置:在开始菜单或我的电脑管理中查找SQL Server 配置管理工具—

网络配置中启动Named Pipes协议和TCP/IP协议,重启数据库服务即可。

windows下编译php7 memcache.dll扩展

最近在配置windows云服务器,安装了最新的php7.0.20,想装个memcache发现官网的memcahce.dll扩展没有支持到php7,

查看了相关的文档决定自己在windows下编译memcache.dll扩展。

由于php_memcache.dll的官方编译出来的版本支持到PHP 5.6就断了,幸运的是,虽然放出的已编译版本停了,但是源码还在更新,

并且支持了7.1。所以,我就只好操起不熟练的VS 2015命令行进行编译适合自己的php_memcache.dll。

1. 下载安装VS 2015,安装是选择全部安装,但占用空间比较大,如果是固态硬盘建议安装可以选择vc++功能。剩下的就等待安装完成了。

2. 编译环境有了,还需要有PHP的sdk,不然还是编译不了,下载地址如下: http://windows.php.net/downloads/php-sdk/

下载划线的两个压缩文件到本地

3.下载memcache源码包,下载地址:https://github.com/websupport-sk/pecl-memcache

4.下载php7.0.20源码 下载地址: http://windows.php.net/downloads/releases/ 下载对应的php源码,我这里是 php-7.0.20-Win32-VC14-x64.zip

5. 编译前的准备,创建一个编译目录 E:\compile,解压php-sdk-binary-tools-20110915.zip里面的文件到compile目录下,

编辑 E:\compile\bin\phpsdk_buildtree.bat,在 GOTO EXIT 前增加代码:
           MD %_%\vc14\x86\deps\bin
           MD %_%\vc14\x86\deps\lib 
           MD %_%\vc14\x86\deps\include
           MD %_%\vc14\x64\deps\bin 
           MD %_%\vc14\x64\deps\lib 
           MD %_%\vc14\x64\deps\include
 注:这是因为phpsdk_buildtree.bat比较旧(毕竟2011年的古董),还不支持VC14,因此需要添加代码让其支持 VC14
6.在开始菜单找到并打开 VS2015 x64 本机工具命令提示符(注:如果要编译32位的,则需进入VS2015 x86 本机工具命令提示符),
 用cd 命令进入 E:\compile,执行如下两条命令: 
bin\phpsdk_setvars.bat 
bin\phpsdk_buildtree.bat phpdev 

7.执行无误后,目录下会生成phpdev文件夹,cd 到 phpdev/vc14/x64目录下,
把deps-7.0-vc14-x64.7z解压到该目录下,覆盖deps文件夹,并把php源代码也解压到x64目录下,将解压后的目录名改为PHP7
   8.在x64目录下创建pecl文件夹,,将下载的memcache代码全部解压到这个目录下改名为memcache,目录结构如下,  再在x64目录下创建obj文件,用来存放编译后的文件
  
















 9. 准备编译;
在刚才的 VS2015 x64 本机工具命令提示符依次执行以下命令,用于创建php编译配置:
cd phpdev\vc14\x64\php7
buildconf 
configure --help >..\configure_help.txt 
configure --disable-all --enable-cli --enable-zlib --enable-hash --enable-session --without-gd 
--with-bz2 --enable-memcache=shared --enable-object-out-dir=..\obj
注:以上参数为编译线程安全版本的php_memcache.dll,如果需要编译非线程安全版本的,需要加入参数 --disable-zts
/确认下安装的php是线程安全还是非线程安全,确认完根据需要选择参数,不然也用不了。
10.如果不出意外,此时就可以使用如下命令来进行编译工作了: nmake 注:这里经常会出问题,具体问题需要大家根据错误原因自行百度解决方法, 
当问题都解决了之后, 就可以在E:\PHPCompile\phpdev\vc14\x64\obj\Release_TS\下找到php_memcache.dll了。 

11.安装,将编译的php_memcache.dll复制到ext目录下,修改php.ini扩展: extension=php_memcache.dll  

12.打印phpinfo,如果存在memcache则表示安装成功,反之检查php_error_log文件. 

13.其他配置按需。在此不在赘述。需要文件可以联系我的邮箱:461488042@qq.com

 

Linux Ubuntu 安装配置 Nginx

  1. 使用sudo apt-get  install  nginx 命令安装Nginx,
  2. 安装 fastcgi 公共网关接口【进程池】: 使用sudo apt-get install  php5-cgi  php5-fpm  命令安装;
  3. nginx 常用命令
    1.   pkill -9 nginx #杀进程,不建议使用
    2. 获取nginx进程号[使用ps命令查看进程或查看/var/log/nginx/nginx.pid文件]    kill -USR2  cat /var/log/nginx/nginx.pid   详情:http://nginx.org/en/docs/control.html
    3. 在nginx安装目录使用nginx -t 测试配置文件语法是否正确
    4. 在nginx安装目录使用nginx -s reload 加载最新配置文件
    5. 在nginx安装目录使用nginx -s stop 立即停止
    6. 在nginx安装目录使用nginx -s quit 优雅的停止  [会在响应完当前请求后停止]
    7. 在nginx安装目录使用nginx -s reopen  重新打开日志,日志备份后,需要执行此命令,重新打开文件,否则会在备份文件继续执行此操作
  4. 修改nginx 配置 在/etc/nginx/sites-avaitnglable/default文件 :

server {    //默认主机段
listen 80 default_server;         //默认端口为80
listen [::]:80 default_server ipv6only=on; //如果开启了ip6则监听ip6的80端口

root /usr/share/nginx/html;   //网站目录路径
index index.html index.htm;    //默认加载的文件名称
server_name localhost;        //服务器名称

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;  //如果文件不存在
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}

location ~ \.php$ {  //如果文件是php文件
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000; #cgi监听的端口
fastcgi_param SCRIPT_FILENAME $DOCUMENT_ROOT$fastcgi_script_name;
fastcgi_index index.php;
}

}

4.nginx.conf文件主要是全局配置段

worker_processes 1; #工作进程使用1个 一般与服务器配置相关,cpu数量*核心数

事件

events{

worker_connections  1024;  #单个进程最大的连接数,与网卡配置对应

}

虚拟主机段在 conf.d 中配置,文件必须是*.conf结尾文件

server

{

listen 80;

server_name www.wenjunting.com;

root  /var/www;  #程序目录

index  index.php index.html;  #默认入口文件

 

location / {
if  ( -f  $request_filename )
{
break;   //请求的文件存在直接跳出
}
if  ( !-e  $request_filename )
{
rewrite ^/(.*)$ /index.php/$1 last;  //文件不存在,重写在index.php并把字符串作为请求参数
break;
}
}

location ~\.php$ {

fastcgi_pass 127.0.0.1:9000;  #cgi监听的端口

fastcgi_index index.php

fastcgi_param SCRIPT_FILENAME $DOCUMENT_ROOT$fastcgi_script_name;

include  fastcgi_params;

try_files $uri = 404;

}

}

5. php cgi 设置端口监听

在 /etc/php5/fpm/pool.d/www.conf 文件中查找 listen = /var/run/php5-fpm.sock;

默认为socket监听,修改为端口监听:

listen = 127.0.0.1:9000

6.重启php5-fpm/nginx;

sudo /etc/init.d/php5-fpm restart

sudo /etc/init.d/nginx restart

 

windows 2008 服务器配置问题

前些天在配置服务器windowns 2008的phpstudy集成环境时,服务器环境安装好了,局域网无法访问的问题,当时也是各种排查,查了几个小时还是没找到问题。

当时的问题是这样的,使用数据库连接工具连不上服务器的数据库(已经配置了mysql的权限),使用局域网的机器ping服务器的IP不通,但是服务器ping局域网ip是可以的,然后就在服务器防火墙入站规则中的一个配置中修改一下参数,然后ping的问题解决了,试着连接还是返回连接不上!

后来查了各种资料,最后在总监的帮助下弄明白了要设置服务器防火墙的入站规则,就单独给mysql设置了端口3306的入站规则,终于连接上数据库了,但网站还是无法访问,一想是不是需要给apache单独配置入站规则?

那就尝试一下吧!按照mysql的协议,配置80端口的入站规则,测试,不行!后面把协议改成任何,测试通过,终于把问题搞定!

商品SKU选择实现

在客户购买商品的时候,若这个商品存在多种”规格”(SKU),就需要客户手动选择自己想要的哪款。当时并不是每种我们都有库存, 所有就需要提供提供一个筛选功能,当客户选中一个条件的时候,需要设置其他条件中的一些值不可选。 这样就能保证不论客户怎么选择,到最后的选择都是有库存的”规格”(SKU)

开始之前先定义几种术语

属性集: 一个商品全部属性的集合

属性: 商品中的 尺码 颜色 就是两个属性

属性值: 尺码、颜色可有多个值 比如 衣服的尺码:S M XL 衣服的颜色:黑色 白色 蓝色 其中 XL 黑色就是属性值

SKU: Stock Keeping Uint(库存量单位) 由属性值组合而成(这些属性值属于不通的属性)如 一件衣服 (XL,白色) 它能确定商品的 唯一性 ,同一款式的衣服 可能有不通的颜色和大小 ,把颜色大小限制住,就能确定这件‘商品’了。

为了简化 我们虚拟出一个的商品, 下面是它的属性集和SKU:

为选择之前是这种显示状态

attr1-attr4中有 2x4x3x2=42种组合,但是有库存的只有上面6种组合

我们要做的就是,在选择某一个属性的时候,把其他为选择的属性中的一些值设置为block(锁定状态) 因为它们和已选属性的组合是没有库存的(有库存的只有上面6种)

比如:
选择 10 和 21后, 有库存的SKU(组合) 只有

attr3中的31 32 以及attr4中的 41 就要设置为block

总结1:在所有库存组合(sku_list)中筛选出包含选中属性值(10,21)组合(10|21|30|40)未选的属性(attr3、attr4)中的所有属性值若不在这个组合中就设置为block

还有一个问题,在已选属性(attr1,attr2)中 , 我可以把21换成2022; 因为 10|21 10|22 也是一种可行组合(有库存),10|23不可行,所以需要2022也可选,23设置为block

或者21不变,修改attr1中的属性值 11|21 不可行,11设置block。

总结2: 已选属性 (attr1,attr2) 中任意一个属性(attr1)的属性值(10,11), 若不能和其他属性(attr2)中的选中属性值(21) 组合成有效(有库存)组合, 则设置该属性(11)为block

好了,接下来就是根据上面总结的两条,来进行程序的实现 点击 商品SKU选择DEMO 可查看demo

 

提高php编程效率的53个小知识点

转载请注明来源:提高php编程效率的53个小知识点

用单引号代替双引号来包含字符串,这样做会更快一些。因为PHP会在双引号包围的字符串中 搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的“函数”(译注:PHP手册中说echo是语言结构,不是真正 的函数,故把函数加上了双引号)。
1、如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍。
2、$row[’id’] 的速度是$row[id]的7倍。
3、echo 比 print 快,并且使用echo的多重参数(译注:指用逗号而不是句点)代替字符串连接,比如echo $str1,$str2。
4、在执行for循环之前确定最大循环数,不要每循环一次都计算最大值,最好运用foreach代替。
5、注销那些不用的变量尤其是大数组,以便释放内存。
6、尽量避免使用__get,__set,__autoload。
7、require_once()代价昂贵。
8、include文件时尽量使用绝对路径,因为它避免了PHP去include_path里查找文件的速度,解析操作系统路径所需的时间会更少。
9、如果你想知道脚本开始执行(译注:即服务器端收到客户端请求)的时刻,使用$_SERVER[‘REQUEST_TIME’]要好于time()。
10、函数代替正则表达式完成相同功能。
11、str_replace函数比preg_replace函数快,但strtr函数的效率是str_replace函数的四倍。
12、如果一个字符串替换函数,可接受数组或字符作为参数,并且参数长度不太长,那么可以考虑额外写一段替换代码,使得每次传递参数是一个字符,而不是只写一行代码接受数组作为查询和替换的参数。
13、使用选择分支语句(译注:即switch case)好于使用多个if,else if语句。
14、用@屏蔽错误消息的做法非常低效,极其低效。
15、打开apache的mod_deflate模块,可以提高网页的浏览速度。
16、数据库连接当使用完毕时应关掉,不要用长连接。
17、错误消息代价昂贵。
18、在方法中递增局部变量,速度是最快的。几乎与在函数中调用局部变量的速度相当。
19、递增一个全局变量要比递增一个局部变量慢2倍。
20、递增一个对象属性(如:$this->prop++)要比递增一个局部变量慢3倍。
21、递增一个未预定义的局部变量要比递增一个预定义的局部变量慢9至10倍。
22、仅定义一个局部变量而没在函数中调用它,同样会减慢速度(其程度相当于递增一个局部变量)。PHP大概会检查看是否存在全局变量。
23、方法调用看来与类中定义的方法的数量无关,因为我(在测试方法之前和之后都)添加了10个方法,但性能上没有变化。
24、派生类中的方法运行起来要快于在基类中定义的同样的方法。
25、调用带有一个参数的空函数,其花费的时间相当于执行7至8次的局部变量递增操作。类似的方法调用所花费的时间接近于15次的局部变量递增操作。
26、Apache解析一个PHP脚本的时间要比解析一个静态HTML页面慢2至10倍。尽量多用静态HTML页面,少用脚本。
27、除非脚本可以缓存,否则每次调用时都会重新编译一次。引入一套PHP缓存机制通常可以提升25%至100%的性能,以免除编译开销。
28、尽量做缓存,可使用memcached。memcached是一款高性能的内存对象缓存系统,可用来加速动态Web应用程序,减轻数据库负载。对运算码 (OP code)的缓存很有用,使得脚本不必为每个请求做重新编译。
29、当操作字符串并需要检验其长度是否满足某种要求时,你想当然地会使用strlen()函数。此函数执行起来相当快,因为它不做任何计算,只返回在zval 结构(C的内置数据结构,用于存储PHP变量)中存储的已知字符串长度。但是,由于strlen()是函数,多多少少会有些慢,因为函数调用会经过诸多步骤,如字母小写化(译注:指函数名小写化,PHP不区分函数名大小写)、哈希查找,会跟随被调用的函数一起执行。在某些情况下,你可以使用isset() 技巧加速执行你的代码。
(举例如下)
if (strlen($foo) < 5) { echo “Foo is too short”$$ }
(与下面的技巧做比较)
if (!isset($foo{5})) { echo “Foo is too short”$$ }
调用isset()恰巧比strlen()快,因为与后者不同的是,isset()作为一种语言结构,意味着它的执行不需要函数查找和字母小写化。也就是说,实际上在检验字符串长度的顶层代码中你没有花太多开销。
34、当执行变量$i的递增或递减时,$i++会比++$i慢一些。这种差异是PHP特有的,并不适用于其他语言,所以请不要修改你的C或Java 代码并指望它们能立即变快,没用的。++$i更快是因为它只需要3条指令(opcodes),$i++则需要4条指令。后置递增实际上会产生一个临时变 量,这个临时变量随后被递增。而前置递增直接在原值上递增。这是最优化处理的一种,正如Zend的PHP优化器所作的那样。牢记这个优化处理不失为一个好 主意,因为并不是所有的指令优化器都会做同样的优化处理,并且存在大量没有装配指令优化器的互联网服务提供商(ISPs)和服务器。
35、并不是事必面向对象(OOP),面向对象往往开销很大,每个方法和对象调用都会消耗很多内存。
36、并非要用类实现所有的数据结构,数组也很有用。
37、不要把方法细分得过多,仔细想想你真正打算重用的是哪些代码?
38、当你需要时,你总能把代码分解成方法。
39、尽量采用大量的PHP内置函数。
40、如果在代码中存在大量耗时的函数,你可以考虑用C扩展的方式实现它们。
41、评估检验(profile)你的代码。检验器会告诉你,代码的哪些部分消耗了多少时间。Xdebug调试器包含了检验程序,评估检验总体上可以显示出代码的瓶颈。
42、mod_zip可作为Apache模块,用来即时压缩你的数据,并可让数据传输量降低80%。
43、在可以用file_get_contents替代file、fopen、feof、fgets等系列方法的情况下,尽量用 file_get_contents,因为他的效率高得多!但是要注意file_get_contents在打开一个URL文件时候的PHP版本问题;
44、尽量的少进行文件操作,虽然PHP的文件操作效率也不低的;
45、优化Select SQL语句,在可能的情况下尽量少的进行Insert、Update操作(在update上,我被恶批过);
46、尽可能的使用PHP内部函数(但是我却为了找个PHP里面不存在的函数,浪费了本可以写出一个自定义函数的时间,经验问题啊!);
47、循环内部不要声明变量,尤其是大变量:对象(这好像不只是PHP里面要注意的问题吧?);
48、多维数组尽量不要循环嵌套赋值;
49、在可以用PHP内部字符串操作函数的情况下,不要用正则表达式;
50、foreach效率更高,尽量用foreach代替while和for循环;
51、用单引号替代双引号引用字符串;
52、“用i+=1代替i=i+1。符合c/c++的习惯,效率还高”;
53、对global变量,应该用完就unset()掉;