HTML <form< 标签的 enctype 属性
首先来了解什么是 <form< 标签的 enctype 属性,enctype 属性规定了在发送到服务器之前应该如何对表单数据进行编码,有三种类型:
属性值 描述
application/x-www-form-urlencoded 默认模式,在发送到服务器之前,所有字符都会进行编码(空格转换为 “+” 加号,特殊符号转换为 ASCII HEX 值)
multipart/form-data 不对字符编码,在使用包含文件上传控件的表单时,必须使用该值。
text/plain 空格转换为 “+” 加号,但不对特殊字符编码。
当在网页提交了一个表单之后,可以使用三种 PHP 方式来获取 Post 数据:$_POST,$HTTP_RAW_POST_DATA,and php://input,有什么区别呢?
$_POST
$_POST 是获取表单 POST 过来数据(body部分)的最常用方法,上传的文件信息使用 $_FILES 获取。
$HTTP_RAW_POST_DATA
当浏览器从表单发送 POST 请求的时候,默认的 media type 是 “application/x-www-form-urlencoded”,意思就是字段名和值都编码了,每个 key-value 对使用 ‘&’ 字符分隔开,key 和 value 使用 ‘=’ 分开,并且 key 和 value 中的空格都会被替换成 + ,其他特殊字符都会被使用 urlencode 方式进行编码。
比如下面的 key-value 对:
name: Jonathan Doe
age: 23
formula: a + b == 13%!
会被编码下面的原始数据:
name=Jonathan+Doe&age=23&formula=a+%2B+b+%3D%3D+13%25%21
PHP 会解析这些原始的 POST 数据,并且格式化成数组,填充到 $_POST 中:
Array
(
[name] => Jonathan Doe
[age] => 23
[formula] => a + b == 13%!
)
$HTTP_RAW_POST_DATA 是 PHP 的一个预定义的变量,用来获取原始的 POST 数据,比如上面的情况下,$HTTP_RAW_POST_DATA 的值就是:
name=Jonathan+Doe&age=23&formula=a+%2B+b+%3D%3D+13%25%21
但是 $HTTP_RAW_POST_DATA 需要在 php.ini 中设置开启:
always_populate_raw_post_data = On
还有一点,$HTTP_RAW_POST_DATA 不支持 enctype=”multipart/form-data” 方式传递的数据,这种情况下,我们要用 $_POST 获取字段的内容,$_FILES 来获取上传的文件信息。
php://input
由于 $HTTP_RAW_POST_DATA 取决于 pho.ini 设置,有没有更好的方法呢?
我们可以使用 php://input 来获取原始的 POST 数据,并且 php://input 比 $HTTP_RAW_POST_DATA 更少消耗内存,当然 php://input 和 $HTTP_RAW_POST_DATA 一样,它也不支持 enctype=”multipart/form-data” 方式传递的数据。
由于 php://input 只是数据流,我们可以使用 file_get_contents() 函数去获取它的内容:
$post_data = file_get_contents('php://input');
print_r($post_data);
获取到的内容和 $HTTP_RAW_POST_DATA 是一样的。
原始的 POST 数据有什么用?
那么原始的 POST 数据有什么用?因为很多时候,接收到不是网页 POST 过来的数据,而是可能通过其他方式 POST 过来的 “text/xml” 格式的数据,这些内容无法解析成 $_POST 数组,这个时候我们就需要原始的 POST 数据进行处理。
WordPress插件的加载顺序其实对于很多朋友来讲都没有必要如何来操作了,但有时安装插件太多了我们需要设置一顺序了那么要如何来安装呢,下面来看看.默认的情况下,WordPress 的插件是按照插件的字母顺序加载的,比如 a/a.php 是比 b/b.php 先加载的,那么我们需要更改插件的加载顺序如何操作呢,由于激活的插件是存在 active_plugins 的 option 里面,我们只需要激活或者停用插件的时候,系统更新 active_plugins 这个 option 值之前 hook 它就可以。
比如下面的代码,我们可以把微信机器人插件设置为最后加载:
add_filter('pre_update_option_active_plugins', 'weixin_robot_set_plugin_load_late');
function weixin_robot_set_plugin_load_late($active_plugins){
$weixin_plugin = plugin_basename(WEIXIN_ROBOT_PLUGIN_FILE);
if(false !== ($plugin_key = array_search($weixin_plugin, $active_plugins))){
unset($active_plugins[$plugin_key]);
$active_plugins[] = $weixin_plugin;
}
return $active_plugins;
}
更多:
一般来说如果插件里面都全是函数,而没有立刻执行的代码,插件的加载顺序是没有关系,如果需要在插件里面有立刻执行的代码,最好放到 plugins_loaded action 里面执行,这样 action 的意思是所有的插件加载完成之后执行的动作。
空白字符在php中有空格也有ascill空格了所以我们要替换需要整理一起来操作,下面来看一个php替换过滤所有的空白字符与空格的例子在php中自带的trim函数只能替换左右两端的空格,感觉在有些情况下不怎么好使,如果要将一个字符串中所有空白字符过滤掉(空格、全角空格、换行等),那么我们可以自己写一个过滤函数。
php学习str_replace函数都知道,可以批量替换的,所以我们可以用如下的源码实现替换过滤一个字符串所有空白字符了。
php源码参考:
<?php
$str = 'jkgsd
gsgsdgs gsdg gsd';
echo myTrim($str);
function myTrim($str)
{
$search = array(" "," ","\n","\r","\t");
$replace = array("","","","","");
return str_replace($search, $replace, $str);
}
?>
运行代码,页面输出:jkgsdgsgsdgsgsdggsd,完美实现了我们想要的效果。
完成这些可以使用PHP的正则表达式来完成
下例可以去除额外Whitespace
<?php
$str = " This line contains\tliberal \r\n use of whitespace.\n\n";
// First remove the leading/trailing whitespace
//去掉开始和结束的空白
$str = trim($str);
// Now remove any doubled-up whitespace
//去掉跟随别的挤在一块的空白
$str = preg_replace('/\s(?=\s)/', '', $str);
// Finally, replace any non-space whitespace, with a space
//最后,去掉非space 的空白,用一个空格代替
$str = preg_replace('/[\n\r\t]/', ' ', $str);
// Echo out: 'This line contains liberal use of whitespace.'
echo "<pre>{$str}</pre>";
?>
这个例子剥离多余的空白字符
<?php
$str = 'foo o';
$str = preg_replace('/\s\s+/', '', $str);
// 将会改变为'foo o'
echo $str;
?>
今天程序突然出现这样的报错
Fatal error: Access level to xxx must be protected (as in class xxx) or weaker in xxx.php on line
原因是子类中定义了与父类一样的方法名
子类:
private function return_json($message,$result='true') {
$data = array();
$data['result'] = $result;
$data['message'] = $message;
self::echo_json($data);
}
private function echo_json($data) {
if (strtoupper(CHARSET) == 'GBK'){
$data = Language::getUTF8($data);//网站GBK使用编码时,转换为UTF-8,防止json输出汉字问题
}
echo json_encode($data);
}
父类:
/**
* 返回json状态
*/
protected function return_json($message,$result='true') {
$data = array();
$data['result'] = $result;
$data['message'] = $message;
self::echo_json($data);
}
protected function echo_json($data) {
if (strtoupper(CHARSET) == 'GBK'){
$data = Language::getUTF8($data);//网站GBK使用编码时,转换为UTF-8,防止json输出汉字问题
}
echo json_encode($data);die;
}
解决办法
把子类中的private 改成 protected,或者避免方法重名。这里例子中很显然是相同的方法进行了重复的定义,子类删除这两个方法即可。
pcntl中的php必须要安装pcntl才可以实现多线程了,在网上找到许多的关于pcntl安装教程,下面整理了一篇比较完整的关于php pcntl安装与使用方法。pcntl中php实现多进程必须要安装的扩展,现将扩展安装步骤写在下面。
一、两种安装方式
1、重新编译PHP的后面configrue提示加上?enable-pcntl。
2、不重新编译php,直接编译安装pcntl扩展。
# cd /usr/local/src/php-5.2.6/ext/pcntl # /usr/local/php/bin/phpize # ./configure ?with-php-config=/usr/local/php/bin/php-config # make && make install
然后将,pcntl.so 加到php.ini中就可以了,使用php -m查看模块命令可以查看已安装的模块。
二、实例
for($x = 1;$x<= 2;$x++){ $pid[$x] = pcntl_fork(); if ($pid[$x] == -1) { die("could not fork"); } elseif ($pid[$x]) { echo "Parent: create ".$pid[$x]."n"; } else { echo "fork ".getmypid()." start:n"; for($i = 0;$i<10;$i++){ echo $x.": ".$i."n"; sleep(1); } exit; } }
本文实例讲述了PHP的pcntl多进程用法。分享给大家供大家参考。具体分析如下:
PHP使用PCNTL系列的函数也能做到多进程处理一个事务。比如我需要从数据库中获取80w条的数据,再做一系列后续的处理,这个时候,用单进程?你可以等到明年今天了。所以应该使用pcntl函数了。
假设我想要启动20个进程,将1-80w的数据分成20份来做,主进程等待所有子进程都结束了才退出:
$max = 800000; $workers = 20; $pids = array(); for($i = 0; $i < $workers; $i++){ $pids[$i] = pcntl_fork(); switch ($pids[$i]) { case -1: echo "fork error : {$i} \r\n"; exit; case 0: $param = array( 'lastid' => $max / $workers * $i, 'maxid' => $max / $workers * ($i+1), ); $this->executeWorker($input, $output, $param); exit; default: break; } } foreach ($pids as $i => $pid) { if($pid) { pcntl_waitpid($pid, $status); } }
这里当pcntl_fork出来以后,会返回一个pid值,这个pid在子进程中看是0,在父进程中看是子进程的pid(>0),如果pid为-1说明fork出错了。
使用一个$pids数组就可以让主进程等候所有进程完结之后再结束了
例子测试
pcntl的扩展的安装就不说了,很简单,这里结合实例说一下pcntl_fork的运行方式
<?php echo $pid= pcntl_fork(); if ($pid == -1) { die('could not fork'); } else if (!$pid) { //这里是子进程 echo '-'; exit(); }else{ //这里是父进程 echo 'A'; echo 'B'; }
我用cli运行多次的结果是
$pid为0说明是子进程,因为pcntl_fork()的作用就是当程序运行到这里,就试图去创建一个子进程,如果创建成果,那么返回当前进程的子进程id,0表示当前进程没有子进程,那么其进程本身不就是子进程了,而如果有进程id,表示其有子进程,那么其不就是父进程。就好像是从这个位置其,下面的所有代码被复制到了另一个进程中执行一样,产生了一个子进程。但是从上面多次执行结果看,大部分情况下是先执行子进程的,这和我之前网上查的资料有些出入,而且这个顺序也不是固定的。但是我们发现倒数第三条,是先执行父进程,后执行的子进程,这时候子进程是有一定风险的,虽然子进程不会死,因为他会过继到1进程,但如果要等待子进程执行完可以这样:
<?php echo $pid= pcntl_fork(); if ($pid == -1) { die('could not fork'); } else if (!$pid) { //这里是子进程 echo '-'; exit(); }else{ //这里是父进程 echo 'A'; pcntl_wait($status);//父进程执行到这里等等子进程执行完再执行 echo 'B'; } 运行结果: 0-31843AB[root@client 60.test.com]# php index.php 0-31845AB[root@client 60.test.com]# php index.php 0-31847AB[root@client 60.test.com]# php index.php 0-31849AB[root@client 60.test.com]# php index.php 0-31851AB[root@client 60.test.com]# php index.php 0-31853AB[root@client 60.test.com]# php index.php 0-31855AB[root@client 60.test.com]# php index.php 31857A0-B[root@client 60.test.com]# php index.php 0-31859AB[root@client 60.test.com]# php index.php 0-31861AB[root@client 60.test.com]# php index.php 0-31863AB[root@client 60.test.com]# php index.php 0-31865AB[root@client 60.test.com]# php index.php 0-31867AB[root@client 60.test.com]# php index.php 0-31869AB[root@client 60.test.com]# php index.php 0-31871AB[root@client 60.test.com]# php index.php 0-31873AB[root@client 60.test.com]# php index.php 0-31875AB[root@client 60.test.com]# php index.php 0-31877AB[root@client 60.test.com]# php index.php 0-31879AB[root@client 60.test.com]# php index.php 0-31881AB[root@client 60.test.com]# php index.php 0-31883AB[root@client 60.test.com]# php index.php
就是我们想要的结果了,其他都没有问题,因为都是先执行的子进程,而这条是先执行了父进程,走到输出A就等子进程执行完才执行的下面的。所以这就是
ntl_wait($status)
的作用。
好了,基本就是这些了。至于进程间或线程间的通信,可以利用类似共享内存变量等的来做。具体情况具体对待吧。