js和php闭包的使用和区别

匿名函数

如果只是省去函数名,单纯的当作一个函数式方法返回,只能称为匿名函数(闭包需要将匿名函数当作结果返回),比如:

// js
var foo = function(x, y) {
    return x + y ;
};
console.log(foo(1, 2));  // 3
<?php
// php
$foo = function($a, $b) {
    return $a + $b;
}; // 一定要加分号
echo $foo(1, 2); // 3

闭包

闭包通常是用来创建内部变量,使得这些变量不得被外部随意修改,而只能通过指定的函数接口去修改

js闭包

这里举一个阮老师博客里的例子,阮老师博客:学习Javascript闭包(Closure)

js基础

参考链接:深入理解JS中声明提升、作用域(链)和this关键字

  • js比较特殊的一点是:函数内部可以直接读取到全局变量(对于阮老师的这句话不是很能理解,大概是想表达的意思:父作用域的变量可以在子作用域直接访问,而不需要去声明访问真正的全局变量?)
    • 大部分语言,变量都是先声明在使用,而对于js,具有声明提升的特性(不管在哪里声明,都会在代码执行前处理)
    • 函数和变量的声明总是会隐式地被移动到当前作用域的顶部,函数的声明优先级高于变量的声明
    • var 会在当前作用域声明一个变量,而未声明的变量,会隐式地创建一个全局变量
// 声明提升
console.log(a);  // 1, 未报错
var a = 1;
// 上文链接中的例子
function testOrder(arg) {
    console.log(arg); // arg是形参,不会被重新定义
    console.log(a); // 因为函数声明比变量声明优先级高,所以这里a是函数
    var arg = 'hello'; // var arg;变量声明被忽略, arg = 'hello'被执行
    var a = 10; // var a;被忽视; a = 10被执行,a变成number
    function a() {
        console.log('fun');
    } // 被提升到作用域顶部
    console.log(a); // 输出10
    console.log(arg); // 输出hello
}; 
testOrder('hi');
/* 输出:
hi 
function a() {
        console.log('fun');
    }
10 
hello 
*/
// 全局作用域
var foo = 42;
function test() {
    // 局部作用域
    foo = 21;
}
test();
foo; // 21
// 全局作用域
foo = 42;
function test() {
    // 局部作用域
    var foo = 21;
}
test();
foo; // 42
  • js变量的查找是从里往外的,直到最顶层(全局作用域),并且一旦找到,即停止向上查找。所有内部函数可以访问函数外部的变量,反之无效
function foo(a) {
    var b = a * 2;
    function bar(c) {
        console.log(a, b, c);
    }
    bar(b * 3);
}
foo(2);
function foo() {
    var a = 1;
}
console.log(a);  //a is not defined
function foo1() {
    var num = 0;
    addNum = function() {  // 这里未通过var去声明,默认是全局变量
        num += 1;
    };
    function foo2() {
        console.log(num);
    }
    return foo2;
}
var tmp = foo1();
tmp();  // 0

addNum();
tmp(); // 1

这里第二次调用foo2函数,foo1函数的局部变量num并没有被初始化为0,说明打印的是内存中的num。正常函数在每次调用结束后都会销毁局部变量,在重新调用的时候会再次声明变量;而这边没有重新声明的原因是:把foo2函数赋值给了一个全局变量tmp,导致foo2函数一直存在内存中,而foo2函数依赖于foo1函数存在,所以foo1函数也存在内存中,并没有被销毁,所以foo1的局部变量也是存在内存中。

  • this的上下文基于函数调用的情况。和函数在哪定义无关,而和函数怎么调用有关。
    • 在全局上下文(任何函数以外),this指向全局对象(windows)
    • 在函数内部时,this由函数怎么调用来确定
      • 当函数作为对象方法调用时,this指向该对象

下面是阮老师博客里的两个思考题:

var name = "The Window";
var object = {
  name : "My Object",
  getNameFunc : function(){
    return function(){
      return this.name;
    };
  }
};
alert(object.getNameFunc()()); // The Window
var name = "The Window";
var object = {
    name : "My Object",
  getNameFunc : function(){
      var that = this;
    return function(){
        return that.name;
    };
  }
};
alert(object.getNameFunc()());// My Object

this的作用域好像一直是个比较奇怪的东西,对于上面两个例子,我的理解是:第一个例子,是在方法里调用的this,而这个this并没有声明,会隐式地创建一个全局变量,所以调用的全局的name;第二个,调用的that的时候,会向顶级链式查找是否声明that,而这个that有this赋值,这里的this又是通过对象方法调用,则该this指向这个object对象,所有最终调用的是object作用域内的name。不知道这么理解是不是有问题,还望大神指正。

那其实js闭包的主要目的:访问函数内部的局部变量,即延长作用域链
参考链接:js闭包MDN文档

php闭包

php回调函数

mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )
mixed call_user_func_array ( callable $callback , array $param_arr )

这两个函数都是把第一个参数作为回调函数d调用,后面接收参数,区别就是第二个函数第二参数接收数组;在使用上唯一的区别就是,call_user_func函数无法接收引用传递; 个人觉得同样是使用,call_user_func 相比call_user_func_array完全可以被替代,不知道是不是有一些性能上的优势。具体使用样例,请参考官方文档。

<?php
// 引用传递
function foo(&$a, &$b) {
    $a ++;
    $b --;
};
$a = $b = 10;
call_user_func_array('foo', [&$a, &$b]);
echo $a."\n", $b; // 11, 9
基本用法

基本用法,跟js的闭包类似
- 普通调用

<?php
global $tmp = 'hello world';
function foo() {
    var_dump(global $tmp);
}
foo(); // null, 函数内部无法直接调用上级作用域的变量,除非声明为全局变量
<?php
$foo1 = function() {
    $a = 10;
    $foo2 = function() {
        var_dump($a);
    };
    return $foo2;
};
$tmp = $foo1();
$tmp();  // null,原因同上 
  • php想要能够获取上级作用域的变量,需要通过use传递
<?php
$foo1 = function () {
    $a = 10;
    $foo2 = function () use ($a) {
        var_dump($a);
        $a ++;
    };
    $foo2();
    return $foo2;
};
$tmp = $foo1();
$tmp();  // 10, 10,  use并不能实际改变变量的值,只是值传递
<?php
$foo1 = function () {
    $a = 10;
    $foo2 = function () use (&$a) {
        var_dump($a);
        $a ++;
    };
    $foo2();
    return $foo2;
};
$tmp = $foo1();
$tmp();  // 10, 11,  通过值传递改变变量的值
  • 下面两段代码的区别,不是很明白,望大佬指点,为什么后一个值传递就可以获取到已经改变后变量的值。好像都是在调用方法之前,已经执行过变量的递增了吧?
<?php
// 值传递
$foo1 = function () {
    $a = 10;
    $foo2 = function () use ($a) {
        var_dump($a);
    };
    $a ++;
    return $foo2;
};
$tmp = $foo1();
$tmp();  // 10
<?php
// 引用传递
$foo1 = function () {
    $a = 10;
    $foo2 = function () use (&$a) {
        var_dump($a);
    };
    $a ++;
    return $foo2;
};
$tmp = $foo1();
$tmp();  // 11
  • 正确使用
<?php
// 值传递
$foo = function () {
    $a = 10;
    $foo2 = function ($num) use ($a) {
        var_dump($num + $a);
    };
    return $foo2;
};
$tmp = $foo();
$tmp(100); // 110
<?php
// 引用传递
$foo = function () {
    $a = 10;
    $foo2 = function ($num) use (&$a) {
        var_dump($num + $a);
        $a ++;
    };
    return $foo2;
};
$tmp = $foo();
$tmp(100); // 110
$tmp(100); // 111
$tmp(100); // 112  跟js类似,保证变量常驻内存
php Closure 类

共同点

都是为了扩展作用域,获取内部变量

区别

js能够在方法内部直接获取到父级作用域的变量,而php需要通过use声明,并且默认是值传递

应用场景

  • 不是很能理解应用场景,搜索了一下,很多只是写了一个闭包实现的购物车,感觉并不是那么的实用。
  • 如果只是单纯的使用匿名函数,感觉还不如封装成一个私有方法
    >这些只是个人粗鄙的理解,望指正.

phpstorm或vscode使用psr2规范

  • 安装composer
  • 全局安装phpcs
composer global require squizlabs/php_codesniffer

vscode直接插件搜索phpcs安装

phpstorm

全局安装phpcs后,会在C:\Users{user name}\AppData\Roaming\Composer\vendor\bin下生成一个phpcs.bat,后面会用到
- phpstorm -> setting
- languages & Frameworks->PHP->Code Sniffer点击Configuration右侧的按钮
- 找到刚才的phpcs.bat,点击Validate,确认
- Editor->Inspection->PHP
- 双击PHP Code Sniffer validation,点击Coding standard右侧的刷新按钮,然后选择psr2,确定

参考链接: 如何优雅地使用phpstorm?

xhprof实际使用过程中的一些注意事项


编	写:袁	亮
时	间:2016-01-12
说	明:xhprof实际使用过程中的一些注意事项

一、扩展安装
	1、前置说明
		1.1 这个组件作为性能分析工具,测试环境有时候不能重现问题
		1.2 直接在生产环境安装,容易导致当前服务受影响或者不可用
		1.3 开启对性能也有一定影响,特别是大流量的情况下,直接全部开始,那就悲剧了
	2、分流开启(成本适中、危险性低)
		2.1 采用nginx分流,使一小部分流量请求发送到安装了xhprof的服务上
		2.2 安装的那台服务器,可用开启监控,并跟生产环境对比
		2.3 既可以达到采集到实际数据,也不影响大部分的用户和业务
	3、流量复制(成本较高,基本无危险)
		3.1 将正式环境的流量复制到测试机上,开启监控查看
		3.2 优点是对原业务几乎无影响,也方便进行流量放大,做压力测试等
		3.3 缺点是之前没做过,略有点麻烦

二、程序开启并记录
	ps:下载http://pecl.php.net/get/xhprof-0.9.2.tgz,参考其中的example/example.php的写法
	
	1、开启监控
		xhprof_enable();
		ps:只在需要的地方开,不要全部开,或者以一定概率开启	
	2、停止监控采集
		$xhprof_data = xhprof_disable();
	3、采集监控数据
		$XHPROF_ROOT = realpath(dirname(__FILE__) .'/..');
		include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_lib.php";
		include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs.php";
		$xhprof_runs = new XHProfRuns_Default('可以保存到自己定义的文件夹中,未设置则采用php中的默认设置');
	4、保存监控数据
		$run_id = $xhprof_runs->save_run($xhprof_data, "保存数据的后缀,作为同一项目的区分用");
		ps:可以将数据保存在一个挂载盘中,这样可以在一台统一的服务器上统一查看调用

	ps:后期也可以考虑自动化,针对慢的请求,直接在php配置中auto_prepend_file增加一段监控程序,按一定比例采样,并汇总分析
	
三、显示性能分析
	1、可以在任意一台能访问存储的监控数据的地方
	2、复制下载文件中的xhprof_html文件夹,并放在可web访问的地方
	3、通过保存时候生成的run_id和自己设置的后缀,即可访问
	4、重点关注callgraph.php,生成的调用链接,主要耗时的调用链有非常明显的颜色标注出来,一眼就能看到性能瓶颈在哪
		ps:这个需要graphviz和graphviz-gd


VIM PHP IDE的基本操作

前言

 安装步骤的链接

关于安装步骤:

  • 分full和fool两个版本,版本差距在自动补全的插件。
  • 最好安装ctags,如果不安装ctags自动补全将不完善,tagbar也无法工作。
  • 可以考虑一下vim的练级攻略

语法检查

文件在保存时会检查语法错误和规范

一共有三种警告:

  • p> php的语法错误, 可以使用:Php主动检查
  • s> 不符合prs2规范, 可以使用:Phpcs主动检查
  • m> 质量检验, 可以使用:Phpmd主动检查

格式修复

vim-php-cs-fixer

nnoremap <silent><F7> :call PhpCsFixerFixDirectory()<CR>
nnoremap <silent><F8> :call PhpCsFixerFixFile()<CR>

F8可以修复一些不符合psr2的规范,但是存在一些问题,如果只是定义了函数名或是类名的一些没有实际作用的代码可能会被删除,安全性有待评估。

自动补全

YCM

full基本操作:

  • 两个字符后开始自动补全
  • tab键选择,shift-tab逆向选择
  • 可以使用ctrl-n向下,或是ctrl-p向上选择

如果是fool版:

  • 不能自动开启补全,不能像图中那样方便。
  • 必须使用<ctrl-x><ctrl-o>开启补全
  • ctrl-nctrl-p无法选择, tab可以使用
  • 其他相同

一般只支持系统函数补全,如果要支持自己编写的函数补全,需要如此:

  1. 在项目顶层目录下执行指令 ctags -R
  2. 必需在项目顶层目录,即ctags文件所在的目录打开vim
  3. 打开文件,不要退出vim,使用NERDTreectrl-p查找和打开文件,如果需要创建文件,可以使用ctrl-p打开文件。
  4. 如果创建了新的类,将必须在项目顶层目录执行ctags -R的指令,当然可以在vim执行:!ctags -R,在不退出vim的情况下更新ctags文件

可以通过tags来实现require的补全

对于composer的补全,默认composer是全局安装的,好像失败了。

代码块

u

已经将php的模板文件软连接到用户主目录下,可以自行查看修改 
vim ~/php.shippets

?-tab 可以生成这样的代码 <?php ?>

f-tab可以生成这样的代码

function ()
{

}

pub-tab可以生成

/*
 * undocumented function
 * @return void
 * /
public function name($param)
{
    return null;
}

c-tab

class filename
{

}

class-tab可以生成一个带注释的class

文件目录和代码浏览

NERDTree 
NERDTree

F2 打开文件目录 
在NERDTree中按?呼出帮助文档

tagbar

需要安装ctags 
tagbar
F3 打开代码浏览

模糊搜索

ctrl-p 
ctrl-p
基本不需要设置

ctrl-p 打开模糊搜索

ctrl-k  ctrl-j 可以在搜索结果中上下选择 
ctrl-t 在新标签页打开 
ctrl-v 分割打开 
ctrl-y 新建文件, 需要先敲入路径和文件名

html tag跳转

在一个html tag上使用%可以跳转与之匹配的tag

官方文档

将光标移动到需要查看的函数上,使用shift-k,就可以查看官方文档a。

符号补全

在使用', ", (, [, {时,会自动补全另一半,同时如果再按各个匹配的另一半,则会跳出。

 

全局搜索

可以使用命令

:CtrlSF param

也可以设置

nmap <leader><leader>f <Plug>CtrlSFPrompt

<leader>默认是\,所以快捷就是 \\f

因为是全局搜索,所以不要在太顶层目录使用,具体请查看CtrlSF

多光标

ctrl-n 开启选择/选择下一个 
下面操作需要在ctrl-n执行后 
ctrl-p 取消一个选择 
ctrl-x 跳过一个选择 
详细vim-multiple-cursor

PS: 可以通过结合全局搜索实现重构

注释

\cc 注释当前行 
\cu 反注释当前行 
可以通过shift-v实现多行操作

撤销树

此处输入图片的描述 
gundo

F4呼出撤销树,查看之前的撤销修改

其它一些插件

php.vim

更好的代码高亮

PHP-Indenting-for-vim

在php 和 html代码混杂在一起时提供更好的缩进

vim-airline

状态栏美化

vim-trailing-whitespace

显示多余的空格

 

php发送邮件的相关知识

编	写:袁	亮
时	间:2015-07-28
说	明:php发送邮件的相关知识

一、什么时候需要用到?
	1、系统监控,应用监控报警
	2、相应的项目统计
	3、用户注册、重置密码
	4、发送推广内容(现在很少)
	5、给用户的正式通知
	
二、php中发送邮件的方式
	1、使用封装好的PHPMailer类发送【常用】
		网上下载相应的类文件即可phpmailer
	2、使用smtp类发送
		与PHPMailer类似
	3、PEAR::Net_SMTP组件
		需要引用pear类库中的Net/SMTP.php和Mail/mime.php,服务器上没有的话,直接下载也可以
		据说挺好用的,很强大,没用过,可以尝试下
	4、内置函数mail
		php需要安装正在运行的邮件系统,了解即可,平时不用
	5、popen管道形式发送
		需要配置邮件服务器,了解即可,我也没用过

三、PHPMailer简单demo
	IsSMTP();//使用smtp协议
	$mail->SMTPDebug = false;
	$mail->Host = "smtp.163.com"; //使用哪个smtp服务器,在对应的邮件设置里找SMTP服务器
	$mail->SMTPAuth = true; //需要认证,必选,基本没有不认证的了
	$mail->Username = "ci123_demo"; //邮箱账号,不需要@什么的,需要在邮箱里开启smtp服务,否则失败
	$mail->Password = "nymqjctyjlykkfpt"; //开启smtp服务的时候系统自动设置的密码(163是这样)

	$mail->CharSet = "UTF-8";//编码设置
	$mail->From = "ci123_demo@163.com";//发件人完整邮箱地址
	$mail->FromName = "育儿网";//发件人备注名,可以随意填写,方便自己看即可

	//发送给谁,可以发给多个人,多次执行AddAddress,前面是邮箱地址,后面是备注
	$mail->AddAddress('yuanliang@corp-ci.com', "袁亮");
	$mail->AddCC('629036398@qq.com','暗夜御林');//抄送,暗送是BCC

	$mail->Subject = '邮件标题';
	$content = '邮件测试内容'.date('Y-m-d H:i:s');
	//$mail->Body = $content;//纯文本内容,不能发送html
	$mail->MsgHTML($content);//以html的形式发送,一般用这个,方便排版

	if(!$mail->Send()){
		echo $mail->ErrorInfo;
		die();
	}
	echo 'succ';
	die();
		
四、PHPMailer注意事项
	1、php需要支持sockets,大部分情况下都开启了,phpinfo查看Sockets Support
	2、最常见的错误是需要开启smtp服务,到对应的邮箱里开启
		smtp服务器地址
		邮箱账号
		授权密码,非邮箱登陆密码
	3、需要发送html内容的,需要使用MsgHTML
	4、发送失败的情况下,第一反应是看报错信息,而不是瞎猜
		
五、邮件发送的注意事项
	1、限制
		每个邮件服务器,都有限制邮件数量,163的限制比较少
		出现莫名其妙收不到的情况,可以尝试换一个账号发,换一个账号收等来测试是哪方面有问题
	2、内容过滤
		垃圾内容过滤是邮件服务器最核心的功能,如果对用户发的时候,需要注意内容是否会被过滤,可以先拿自己的账号测试
	3、发送附件
		AddAttachment('文件绝对路径','附件名称');
		
六、邮件协议
	1、POP3
		1.1 POP3允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件
		1.2 POP3协议允许电子邮件客户端下载服务器上的邮件,但是在客户端的操作(如移动邮件、标记已读等),不会反馈到服务器上
			比如通过客户端收取了邮箱中的3封邮件并移动到其他文件夹,邮箱服务器上的这些邮件是没有同时被移动的
	2、IMAP
		2.1 交互式邮件存取协议,它是跟POP3类似邮件访问标准协议之一
		2.2 IMAP提供webmail 与电子邮件客户端之间的双向通信,客户端的操作都会反馈到服务器上,
			对邮件进行的操作,服务器上的邮件也会做相应的动作
		2.3 IMAP像POP3那样提供了方便的邮件下载服务,让用户能进行离线阅读
	3、SMTP
		3.1 简单邮件传输协议;它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式
		3.2 SMTP认证,就是要求必须在提供了账户名和密码之后才可以登录 SMTP 服务器,现在已经没有不需要认证的了,除非自己搭
		3.3 发送邮件,必须是开的这个服务
		
附录:
	http://www.w3school.com.cn/php/php_ref_mail.asp
	http://blog.csdn.net/heiyeshuwu/article/details/458170
	http://blog.csdn.net/rainday0310/article/details/6281936
	http://help.163.com/09/1223/14/5R7P6CJ600753VB8.html

php序列化对象导致的错误


编	写:袁	亮
时	间:2014-04-11
说	明:序列化对象导致的错误

一、问题描述
	在迁移blogadmin项目的时候遇到了一个报错:(迁移前php版本:5.2.6、迁移后php版本:5.3.7)

	Fatal error: PostsController::index(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "Information" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition

二、解决过程
	1、根据报错信息搜索,查找到文档:http://www.php.net/manual/zh/language.oop5.serialization.php
	2、按文档里的说明,结合程序,出现问题的原因是:
		a、程序中,会把对象存储会话中(session,session会调用php的serialize函数序列化对象)
		b、在新的页面中,程序从session中,取出数据,并自行调用unserialize函数,反序列化对象,并且正常使用对象
		c、以上要正常使用,必须保证对象所对应的类定义要在unserialize之前,否则反序列化出来的对象会有缺失,从而导致错误
		d、一般情况下,调整session_start和引用类定义文件的顺序即可
		
	3、根据上述信息,调试程序,发现调用对象的时候,类已经定义,而且类定义的引用在session_start之前
	4、经查,发现是该服务器的php配置中,自动开启了session_start,导致session_start永远在类定义前,从而导致错误发生
	5、修改php配置,并重启apache即可

	

php扩展安装的大概流程


编	写:袁	亮
时	间:2015-07-27
说	明:php扩展安装的大概流程

一、安装流程
	1、找到php源码包,进入ext目录
		1.1 注意,是源码包,而不是安装之后的那个文件夹,类似于windows,下载了一个软件包(源码包),安装到了另外一个目录
			使用的时候是直接用的安装好的目录下的程序,而要装扩展,需要的是源码包里的东西
		1.2 注意版本问题,最好是跟已经安装的php同一个版本的源码包,否则很可能会失败
		1.3 例如:192.168.0.249 
			cd /opt/software/centos/php-5.3.27/ext/pdo_mysql
	2、/opt/ci123/php/bin/phpize
		2.1 需要在扩展的那个目录下执行
		2.2 根据自己的php安装目录,找到bin/phpize
		2.3 正常的话,会生成configure
	3、 ./configure --with-php-config=/opt/ci123/php/bin/php-config --with-pdo-mysql=/opt/ci123/mysql/
		3.1 with-pdo-mysql非必须,其他是安装任何扩展都需要的
		3.2 必须在ext目录下执行
	4、make && make install
		4.1 没问题的话,会在最后输出一个目录,看下目录里是否有生成对应的.so文件,比如这次的就是pdo_mysql.so
	5、修改php配置文件,将扩展添加进去
		5.1 php.ini文件,可以通过phpinfo得到其路径,如果那个目录下没有,可以拷贝一份php.ini文件
		5.2 在末尾增加
			[pdo_mysql]
			extension=pdo_mysql.so
	6、验证模块是否正确添加
		php -m|grep pdo_mysql
		ps:如果有输出才算正常
	7、重启http服务,重新加载php
		/opt/ci123/apache/bin/apachectl -t
		/opt/ci123/apache/bin/apachectl restart
		ps:必须-t先检查下配置文件是否正常,别到时候其他人把apache配置改错了,但是因为没重启没问题,被你重启出问题来了
		
		

php性能分析工具xhprof – 基础使用


编	写:袁	亮
时	间:2015-07-24
说	明:php性能分析工具xhprof-基础使用

一、简单介绍
	1、由Facebook开源的一个php性能分析工具
	2、统计函数级别的请求次数,执行时间,阻塞时间,CPU和内存使用情况等
	3、分析一个复杂项目的性能瓶颈时非常有用,很直观的看出问题在哪
	4、也可以用这个来绘制调用的关系图,方便代码理解

二、安装扩展
	1、下载扩展包
		wget http://pecl.php.net/get/xhprof-0.9.2.tgz  
	2、解压
		tar zxvf  xhprof-0.9.2.tgz
	3、安装
		cd xhprof-0.9.2/extension/
		/opt/ci123/php/bin/phpize
		./configure --enable-xhprof --with-php-config=/opt/ci123/php/bin/php-config
		make
		make install
	4、修改php.ini配置文件
		vim /opt/ci123/php/etc/php.ini
		最后,加上:
			[xhprof]
			extension=xhprof.so
			xhprof.output_dir=/tmp/xhprof
		ps:目录需要保证apache有读写权限,最后不能带/,否则会报错
	5、检验是否成功
		/opt/ci123/php/bin/php -m|grep 'xhprof'
	6、重启apache
		/opt/ci123/apache/bin/apachectl -t
		/opt/ci123/apache/bin/apachectl restart

三、自带的范例运行
	1、将解压出来的文件夹,复制到一个apache可访问的目录,extension目录不需要
	2、浏览器访问该目录下的examples/sample.php
	3、查看最后输出的提示,访问对应的链接,有相应的分析,xhprof_html/index.php
	4、出不了图的话,安装下graphviz,默认不支持png,需要再装一个gd的
		yum install graphviz
		yum install graphviz-gd
	
四、简单试用
	1、blog.geekman.vip分析
	2、首页,调用了99,829个函数
	3、可以进行各种排序,查看时间主要耗在哪些函数上
	4、可以查看整个运行过程中的性能瓶颈,图片格式,很直观
	5、范例:
		http://192.168.0.249/xhprof/xhprof_html/?run=55b1de2f8613a&source=xhprof_foo
	
附录:
	http://mirror.facebook.net/facebook/xhprof/doc.html
	http://avnpc.com/pages/profiler-php-performance-online-by-xhprof
	http://www.cnxct.com/you-do-not-have-dot-image-generation-utility-installed/
	

file_get_contents了解:自定义http请求

编	写:袁	亮
时	间:2015-07-17
说	明:file_get_contents了解:自定义http请求

一、使用原因
	1、这是一个使用非常频繁的函数,对应的file_put_contents,都是文件操作中第一选择
	2、抓取网络内容,一般情况下,也是使用的这个,但遇到稍微麻烦点的,我们就觉得没法子了
	3、curl等能做的,其实file_get_contents也基本上都能做,只是大家不熟悉
	
二、简单范例,直接看php.net
	array(
		'method'=>"GET",
		'header'=>"Accept-language: en\r\n" .
				  "Cookie: foo=bar\r\n"
	  )
	);

	$context = stream_context_create($opts);

	// Open the file using the HTTP headers set above
	$file = file_get_contents('http://www.example.com/', false, $context);
	
三、核心函数 stream_context_create
	1、支持以下协议,生成相应资源流上下文
		http://php.net/manual/zh/wrappers.php
		file:// — 访问本地文件系统
		http:// — 访问 HTTP(s) 网址
		ftp:// — 访问 FTP(s) URLs
		php:// — 访问各个输入/输出流(I/O streams)
		zlib:// — 压缩流
		data:// — 数据(RFC 2397)
		glob:// — 查找匹配的文件路径模式
		phar:// — PHP 归档
		ssh2:// — Secure Shell 2
		rar:// — RAR
		ogg:// — 音频流
		expect:// — 处理交互式的流
	
	2、http资源流支持参数:
		http:http://php.net/manual/zh/context.http.php
		http协议支持的参数,基本都支持
		header头,post数据,user_agent,代理,超时,跟随重定向等等
		
	3、post数据设置范例
		$postdata = http_build_query(
			array(
				'var1' => 'some content',
				'var2' => 'doh'
			)
		);
		$opts = array('http' =>
			array(
				'method'  => 'POST',
				'header'  => 'Content-type: application/x-www-form-urlencoded',
				'content' => $postdata
			)
		);
		$context = stream_context_create($opts);
		$result = file_get_contents('http://example.com/submit.php', false, $context);
		

coreseek排错:api版本不对导致搜索错误

编	写:袁	亮
时	间:2015-07-17
说	明:coreseek搜索的一个小提示

一、问题描述
	1、在本地254上,搭建了3.2.14 版本的coreseek服务端
	2、searched进程启动
	3、命令行模式下搜索有数据
	4、使用php的api搜索,没有返回值,也没有报错
	
二、问题排查
	1、使用api搜索的,如果出现问题,第一反应输出其本身的错误信息,last_error还是什么的,查一下
	2、api的版本和coreseek的版本不一致,导致不能搜索
	3、找到对应版本的php api即可