PHP面向对象的自动加载机制

在学习PHP的面向对象的时候,会知道很多“语法糖”,也就是魔术方法。有一个加自动加载的魔术方法,叫:__autoload();

先看一段代码

[php]

<?php
function __autoload($classname) {
$filename = "./". $classname .".php";
include_once($filename);
}

new a();

[/php]

这里实例化了一个A类,但在代码块中没有A类的相关代码,按常理是应该会报错,因为没有找到对应的A类,但如果你使用了autoload()自动加载函数的话,结果就可以能不一样

QQ截图20150527203846

 

从上面的流程图:在页面实例化一个新类,就会先在当前目录找对应的类代码,如果没有就去autoload堆栈找对应的自动加载函数,如果有的话就自动加载该类,没有话就抛出错误。

这是PHP自动加载的一个机制。然后重点在后面。如果我有多个自动加载的函数,怎么办! 

PHP提供了一个SPL函数

[php]

spl_autoload_register(); // 注册autoload函数

[/php]

官方:spl_autoload_register() 提供了一种更加灵活的方式来实现类的自动加载。因此,不再建议使用 __autoload() 函数,在以后的版本中它可能被弃用。

然而在PHPexecl 和 PHPWord 里面都使用到了 这个函数来做自动加载,但两者有区别!!

PHPexecl 自动加载的方法(这里作者估计是Python工程师,不然花括号都没有,用缩进来表示)

[php]

public static function Register() {
$functions = spl_autoload_functions();
foreach ( $functions as $function)
spl_autoload_unregister($function);
$functions = array_merge(array(array(‘PHPExcel_Autoloader’,’Load’)),$functions);
foreach ( $functions as $function)
$x = spl_autoload_register($function);
return $x;
}

[/php]

PHPWord 自动加载的方法

[php]
public static function Register() {
return spl_autoload_register(array(‘PHPWord_Autoloader’, ‘Load’));
}
[/php]

这两种方法,都可以完成重定义自动加载,但有区别? 如果是独立运行代码,两种情况都可以运行,但要是整合到框架中,比如YII框架。那么PHPWord的自动加载就无效了。

因为YII框架自动带有自动加载函数,而且再代码运行的时候就已经注册了,而spl_autoload_register()会将新的自动加载函数,加载autoload队列的后面。所有PHPWord在运行的时候

就调用的是YII框架定义的自动加载机制,而且不是PHPWord这种加载方式。

所以反过来看PHPexecl的加载函数,你就明白了。

将HTML页面转行成word并且保存

这里用使用到一个PHP的工具叫:PHPWord。

生成Word的原理是,将堆规定好了的xml压缩成一个zip包,并且把后缀名改成doc或者docx即可。

所以使用PHPWord,需要你的PHP环境安装zip.dll压缩扩展,我写了一个demo.

Deom演示:http://www.dengwz.com/phpword/index.html 往里面贴一个URL就可以了

功能说明:

20150507 — HTML中的<p>标签和<ol>列表标签的获取

20150508 — 新增获取文章中的图片功能

20150509 — 新增行间距,并且过滤一下错误图片

20150514 — 新增表格处理,并且将代码改成面向对象

20150519 — 新增GD库处理网络图片

[php]

&amp;nbsp;require_once 'PHPWord.php';
 require_once 'SimpleHtmlDom.class.php';

 class Word{

 private $url;
 private $LinetextArr = array();
 public $CurrentDir;
 public $error = array(); //错误数组
 public $filename = null;
 public $Allowtag = "p,ol,ul,table";

 /**数据统计**/
 public $DownImg = 0;
 public $expendTime = 0;
 public $HttpRequestTime = 0;
 public $ContentLen = 0;
 public $HttpRequestArr = array();
 public $expendmemory = 0;

 public function __construct($url)
 {
 $startTime = $this-&amp;gt;_Time();
 $startMemory = $this-&amp;gt;_memory();

 $this-&amp;gt;url = $url;

 $UrlArr = parse_url($this-&amp;gt;url);

 $this-&amp;gt;host = $UrlArr["scheme"]."://".$UrlArr['host'];

 $this-&amp;gt;CurrentDir = getcwd();

 $this-&amp;gt;LinetextArr["table"] = array();

 $html = new simple_html_dom($this-&amp;gt;url);

 $this-&amp;gt;HttpRequestArr[] = $this-&amp;gt;url;
 $this-&amp;gt;HttpRequestTime++;

 foreach($html-&amp;gt;find($this-&amp;gt;Allowtag) as $key=&amp;gt;$value)
 {
 if($value-&amp;gt;tag == "table")
 {
 $this-&amp;gt;ParseTable($value,0,$this-&amp;gt;LinetextArr["table"]);
 }
 else
 {
 $this-&amp;gt;AnalysisHtmlDom($value);
 }

 $this-&amp;gt;error[] = error_get_last();

 }

 $endTime = $this-&amp;gt;_Time();
 $endMemory = $this-&amp;gt;_memory();

 $this-&amp;gt;expendTime = round(($endTime-$startTime),2); //微秒
 $this-&amp;gt;expendmemory = round(($endMemory-$startMemory)/1000,2); //bytes

 $this-&amp;gt;CreateWordDom();

 }

 private function _Time()
 {
 return array_sum(explode(" ", microtime()));
 }

 private function _memory()
 {
 return memory_get_usage();
 }

 /**
 * 解析HTML中的Table,这里考虑到多层table嵌套的情况
 * @param $value HTMLDOM
 * @param $i 遍历层级
 * **/
 private function ParseTable($value,$i,$Arr)
 {
 if($value-&amp;gt;firstChild() &amp;amp;&amp;amp; in_array($value-&amp;gt;firstChild()-&amp;gt;tag,array("table","tbody","thead","tfoot","tr")))
 {
 foreach($value-&amp;gt;children as $k=&amp;gt;$v)
 {
 $this-&amp;gt;ParseTable($v,$i++,$Arr);
 }
 }
 else
 {
 foreach($value-&amp;gt;children as $k=&amp;gt;$v)
 {

 if($v-&amp;gt;firstChild() &amp;amp;&amp;amp; $v-&amp;gt;firstChild()-&amp;gt;tag != "table")
 {
 $Arr[$i][] = array("tag"=&amp;gt;$v-&amp;gt;tag,"text"=&amp;gt;trim($v-&amp;gt;plaintext));
 }

 if(!$v-&amp;gt;firstChild())
 {
 $Arr[$i][] = array("tag"=&amp;gt;$v-&amp;gt;tag,"text"=&amp;gt;trim($v-&amp;gt;plaintext));
 }
 }

 }
 }

 /**
 * 解析HTML里面的表情
 * @param $value HTMLDOM
 * **/
 private function AnalysisHtmlDom($value)
 {
 $tmp = array();
 if($value-&amp;gt;has_child())
 {
 foreach($value-&amp;gt;children as $k=&amp;gt;$v)
 {
 $this-&amp;gt;AnalysisHtmlDom($v);
 }
 }
 else
 {
 if($value-&amp;gt;tag == "a")
 {
 $tmp = array("tag"=&amp;gt;$value-&amp;gt;tag,"href"=&amp;gt;$value-&amp;gt;href,"text"=&amp;gt;$value-&amp;gt;innertext);
 }
 else if($value-&amp;gt;tag == "img")
 {
 $src = $this-&amp;gt;unescape($value-&amp;gt;src);
 $UrlArr = parse_url($src);

 if(!isset($UrlArr['host']))
 {
 $src = $this-&amp;gt;host.$value-&amp;gt;src;
 $UrlArr = parse_url($src);
 }

 $src = $this-&amp;gt;getImageFromNet($src,$UrlArr); //表示有网络图片,需要下载

 if($src)
 {
&amp;nbsp;  $imgsArr = $this-&amp;gt;GD($src);
   $tmp = array("tag"=&amp;gt;$value-&amp;gt;tag,"src"=&amp;gt;$src,"text"=&amp;gt;$value-&amp;gt;alt,"width"=&amp;gt;$imgsArr['width'],"height"=&amp;gt;$imgsArr['height']); }
 }
 else
 {
 $tmp = array("tag"=&amp;gt;$value-&amp;gt;tag,"text"=&amp;gt;strip_tags($value-&amp;gt;innertext));
 } 

 $this-&amp;gt;LinetextArr[] = $tmp;
 }

 }

 /**
 * 根据GD库来获取图片的如果太多,进行比例压缩
 * **/
 private function GD($src)
 {
 list($width, $height, $type, $attr) = getimagesize($src);

 if($width &amp;gt; 800 || $height &amp;gt; 800 )
 {
 $width = $width/2;
 $height = $height/2;
 }

 return array("width"=&amp;gt;$width,"height"=&amp;gt;$height);
 }

 /**
 * 将Uincode编码转移回原来的字符
 * **/
 public function unescape($str) {

 $str = rawurldecode($str);

 preg_match_all("/(?:%u.{4})|&amp;amp;#x.{4};|&amp;amp;#\d+;|.+/U",$str,$r);

 $ar = $r[0];

 foreach($ar as $k=&amp;gt;$v) {

 if(substr($v,0,2) == "%u"){

 $ar[$k] = iconv("UCS-2BE","UTF-8",pack("H4",substr($v,-4)));
 }

 elseif(substr($v,0,3) == "&amp;amp;#x"){

 $ar[$k] = iconv("UCS-2BE","UTF-8",pack("H4",substr($v,3,-1)));

 }
 elseif(substr($v,0,2) == "&amp;amp;#"){

 $ar[$k] = iconv("UCS-2BE","UTF-8",pack("n",substr($v,2,-1)));
 }
 }

 return join("",$ar);

}

 /**
 * 图片下载
 * @param $Src 目标资源
 * @param $UrlArr 目标URL对应的数组
 * **/
 private function getImageFromNet($Src,$UrlArr)
 {
 $file = basename($UrlArr['path']);

 $ext = explode('.',$file);

 $this-&amp;gt;ImgDir = $this-&amp;gt;CurrentDir."/".$UrlArr['host'];

 $_supportedImageTypes = array('jpg', 'jpeg', 'gif', 'png', 'bmp', 'tif', 'tiff');

 if(isset($ext['1']) &amp;amp;&amp;amp; in_array($ext['1'],$_supportedImageTypes))
 {
 $file = file_get_contents($Src);

 $this-&amp;gt;HttpRequestArr[] = $Src;
 $this-&amp;gt;HttpRequestTime++;

 $this-&amp;gt;_mkdir(); //创建目录,或者收集错误

 $imgName = md5($UrlArr['path']).".".$ext['1'];

 file_put_contents($this-&amp;gt;ImgDir."/".$imgName,$file);

 $this-&amp;gt;DownImg++;

 return $UrlArr['host']."/".$imgName;
 }

 return false;
 }

 /**
 * 创建目录
 * **/
 private function _mkdir()
 {

 if(!is_dir($this-&amp;gt;ImgDir))
 {
 if(!mkdir($this-&amp;gt;ImgDir,"7777"))
 {
 $this-&amp;gt;error[] = error_get_last();
 }
 }
 }

 /**
 * 构造WordDom
 * **/
 private function CreateWordDom()
 {

 $PHPWord = new PHPWord();

 $PHPWord-&amp;gt;setDefaultFontName('宋体');
 $PHPWord-&amp;gt;setDefaultFontSize("11");

 $styleTable = array('borderSize'=&amp;gt;6, 'borderColor'=&amp;gt;'006699', 'cellMargin'=&amp;gt;120);
 // New portrait section
 $section = $PHPWord-&amp;gt;createSection();

 $section-&amp;gt;addText($this-&amp;gt;Details(),array(),array('spacing'=&amp;gt;120));

 //数据进行处理
 foreach($this-&amp;gt;LinetextArr as $key=&amp;gt;$lineArr)
 {
 if(isset($lineArr['tag']))
 {
 if($lineArr['tag'] == "li")
 {
 $section-&amp;gt;addListItem($lineArr['text'],0,"","",array('spacing'=&amp;gt;120));
 }
 else if($lineArr['tag'] == "img")
 {
 $section-&amp;gt;addImage($lineArr['src'],array('width'=&amp;gt;$lineArr['width'], 'height'=&amp;gt;$lineArr['height'], 'align'=&amp;gt;'center'));
 }
 else if($lineArr['tag'] == "p")
 {
 $section-&amp;gt;addText($lineArr['text'],array(),array('spacing'=&amp;gt;120));
 }
 }
 else if($key == "table")
 {
 $PHPWord-&amp;gt;addTableStyle('myOwnTableStyle', $styleTable);
 $table = $section-&amp;gt;addTable("myOwnTableStyle");
 foreach($lineArr as $key=&amp;gt;$tr)
 {
 $table-&amp;gt;addRow();
 foreach($tr as $ky=&amp;gt;$td)
 {
 $table-&amp;gt;addCell(2000)-&amp;gt;addText($td['text']);
 }
 }
 }
 }

 $this-&amp;gt;downFile($PHPWord);
 }

 public function Details()
 {
 $msg = "一共请求:{$this-&amp;gt;HttpRequestTime}次,共下载的图片有{$this-&amp;gt;DownImg}张,并且下载完成大约使用时间:{$this-&amp;gt;expendTime}秒,整个程序执行大约消耗内存是:{$this-&amp;gt;expendmemory}KB,";

 return $msg;
 }

 public function downFile($PHPWord)
 {
 if(empty($this-&amp;gt;filename))
 {
 $UrlArr = parse_url($this-&amp;gt;url);
 $this-&amp;gt;filename = $UrlArr['host'].".docx";
 }

 // Save File
 $objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007');
 $objWriter-&amp;gt;save($this-&amp;gt;filename);

 header("Pragma: public");
 header("Expires: 0");
 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
 header("Cache-Control: public");
 header("Content-Description: File Transfer");

 //Use the switch-generated Content-Type
 header('Content-type: application/msword');//输出的类型

 //Force the download
 $header="Content-Disposition: attachment; filename=".$this-&amp;gt;filename.";";
 header($header);
 @readfile($this-&amp;gt;filename);
 }
}

[/php]

上面的代码重点感觉不是word生成,而是Simplehtmldom的使用,这是一个开源的HTML解析器,之前有提到,这几天在看他的代码,

引出了两个学习方向

  1. 正在表达式
  2. 这个扩展的函数整理

看源代码的收获:

PHP的异常是可以捕获的,而且PHP的错误也是可以捕获的。

[php]

error_get_last() &amp;nbsp;//用这个函数可以捕获页面中的PHP错误,不谢。

[/php]

用PHP在innodb引擎下,快速代建全文搜索功能

需要准备的设备:Liunx(Centos)操作系统(只支持Linux),PHP环境。

这里介绍一个国人开发的搜索引擎开源项目—讯搜(xunsearch),它分为:索引服务器和搜索服务器。

在CentOS下面愉快的代建服务器

[php]

wget http://www.xunsearch.com/download/xunsearch-full-latest.tar.bz2

tar -xjf xunsearch-full-latest.tar.bz2

[/php]

准备安装了

cd xunsearch-full-1.3.0/ sh setup.sh      //这里可以能遇到安装失败的问题,是因为没有安装gcc gcc-c++ 这样的扩展。用yum 安装十分简单

安装的时候要你输入安装目录,一般是 /usr/local/xunsearch  回车然后再输入Y回车,安装有点漫长。。

等待安装完成之后

具体操作请参照这里 : http://www.iterror.cn/q-1.html

安装完成后,怎么跨服务器来访问:

[php]

安装目录(/usr/local/xunsearch/)+bin/xs-ctl.sh -b a.b.c.d start // 监听在指定 IP 上 使用这个,把监听绑定到指定的外网能访问的IP上面。我的是 192.168.1163.130
[/php]

还有需要使用iptables 来开放8383和8384端口。最简单的是关闭iptables.

======================================================

PHP-SDK 配置文件修改,如下修改

[php]

[配置文件]

project.name = demo

project.default_charset = utf-8

server.index = 192.168.116.130:8383  //索引服务器的地址,默认是8383

server.search = 192.168.116.130:8384 //搜索服务器的地址,默认是8384

[pid]

type = id

[subject]

type = title  //设置被索引字段

[message]

type = body   //设置被索引字段

[chrono]

type = numeric

[配置文件]

[/php]

====================================================

具体使用细节就请查考使用手册:http://www.xunsearch.com/doc/php/guide/index.overview

性能测试:

测试结果数据

湖南工业大学-校园助手!从开始到现在

找了一个Bootstrap管理系统的设计页面,然后就开始整理这几年来的一直在陆陆续续做的一个系统–校园助手。

主要实现的功能:成绩查询,课表功能,计算总平均分和总绩点。

工大圈 - 湖南工业大学最大的校内

这是管理系统的管理界面。(上面的数据是真实的!!可惜不是我的)

开始我只打算做了WEB版,然后有几个小兄弟说要过来帮忙做APP!然后马上马不停蹄就出了APP。所有人都是没经验的,都摸着石头过河

QQ图片20150301184154

这是是APP的展示页面。。 反正我挺喜欢的。

好了APP和WEB功能就先介绍到这个,现在主要开发的过程。

==== 华丽的分割线====

当时想做一个关于正方教务系统的扩展系统。那是大二的时候,因为饱受正方系统抢课的摧残。

可惜:当时年轻,只有想法,没有能力。当时拦着的就是验证码的问题!远程提交表单。

机遇:当年在酷狗音乐实习,要做一个自动化测试工具,就是用CURL去请求URL并且读取CSV文件去调用接口。

结果:学会了CURL远程登录原理。这里在之前的文章中有提到。

但时间已经到了大四,但是是通过手动输入验证码的方式登录教务系统。

但需求远远不能被满足,因为之前是想法是,只要在这里登录一次,在不修改密码的前提下,要最快更新成绩。

这样时间到了毕业季,偶尔看到一个也是正方教务系统的学校做的微信公共帐号,这样!给一直想绕过验证码的我提供了思路。

然后,就有你看到的这个系统上线。

=====又是华丽的分割线======

20150228 离预计发布APP的日子还有一天!在连续奋斗十几个小时后,终于联调完成。发布了APP 0.1版。

该APP只有三个功能:成绩查询(统计暂时未通过的课程,平均分,绩点和历年成绩)。四六级成绩,校历

WEB端也新增了定时采集列队。通过主从MYSQL,将数据的读写分离,用Redis的消息列队来采集成绩。

说说这十几个小时,满满都是正能量。当时小哥说,这逻辑都知道了,12点之前应该能发布!只要联调好API.

但当联调好API的时候,就应该凌晨1点了,安卓数据展示界面还没写好。(扯淡一般的预估,这里主要的问题还在我,我对API的文档书写的不规范,造成了很多的沟通,增加了开发成本)

然后时间一秒一秒的过去,实在是扛不住了,我们已经看到广州凌晨5点的天色。

后记

因为还没有做压力测试和服务端中间件来均衡流量。不敢马上发布出去,先拉内测用户。

整整两年了,说不出的感觉,反正幸好没有放弃,这里谢谢几个小哥的支持。才能盼到这个APP上线。

虽然这个APP也好,WEB端也好,没有办法盈利,但它是我大学的一个梦想。我就是要做它,而且要做好它。

远程登录正方教务系统(绕过验证码篇)

我都不想说什么,我研究了半年的验证码识别,最后发现,原来正方教务系统登录方式可以绕过验证码,,简直吐血

开始打算做一个采集教务系统成绩和课表的功能,但验证码成了拦路虎。

我“机智”用获取验证码,然后cookies记录验证码,再跟正方服务器对比来完成验证码登录,,最后发现这步可以直接跳过去。

正方有一个功能:后台开启验证码,就是他的验证码功能是可选的。说不白了,就是你不请求服务器就不会生成验证码。

然后,你只需要几行代码就是完成远程登录教务系统,主要隐藏域

[php]

public function login(){
$url = C(‘School_url’)."default2.aspx";
$post[‘__VIEWSTATE’] = ‘dDwyODE2NTM0OTg7Oz69gdYBizSXHwj9xCoAQeszC5eGfw==’;
$post[‘__VIEWSTATEGENERATOR’] = ‘92719903’;
$post[‘txtUserName’] = ‘学号’;
$post[‘TextBox2’] = ‘密码’;
$post[‘txtSecretCode’] = ”;
$post[‘lbLanguage’] = ”;
$post[‘RadioButtonList1’] = iconv(‘utf-8’, ‘gb2312’, ‘学生’);
$post[‘Button1’] = iconv(‘utf-8’, ‘gb2312’, ‘登录’);
$result = $this->curl_Login($url,$post);
print_r($result);
return $result;
}

[/php]

然后是CURL请求的代码,,记得cookies这个东西是必须要有的,PHP开启的curl跟游览器不是一个进程,不共用cookies

所以要用CURL的抓取cookies的方法

[php]

curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file); //在CURL请求中发送cookies值

curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file); //在CURL请求中,把head头的cooked存入到指定的文件中

[/php]

使用这两个方法就能操作curl中的cookies。

然后,,你就会发现,你没有输入验证码通过学号和密码就已经登录到教务系统了。然后怎么回去成绩和课表呢?

 

PHP后台远程登录正方教务系统

从去年想这个事情怎么解决,今年终于算是把他搞清楚了,但验证码必须要填。

如果你能像360抢票哪有自动识别验证码,那就没事了。废话不多扯了。回归正题

这里要用CURL。

设计思路:先登录页面获取COOKIES,然后拿着cookies找服务器要验证码。最后提供服务器需要的全部信息。

(这种思维是完全模拟游览器访问页面,根本区别出来是人还机器)

[php]
public function index(){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); //填对于的URL就可以了
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file); //主要cookie的路径,本保存页面cookie
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); //返回结果自动输出
$response = curl_exec($ch);
curl_close($ch);
}
[/php]

访问正方教务系统的首页,第一获取页面中的HTML,第二是获取cookies。 继续阅读

LOL数据远程获取

好久没更新博客了,主要最近有一个想法,打算把它实现出来。

过几天网站就要上线了。

最近完成了一个小功能,就是LOL数据获取,

比如:我给你一个号,你把这个号是否打过排位?战斗力是多少?胜率和所在的总场数数据获取过来

数据都在多玩的网站上可查,所以该做的功能就是远程抓取。

LOL数据图

LOL数据图

功能没啥亮点,就是简单的实现。 继续阅读

PHP的文件上传处理

最近遇到一个事,把自己坑了好久,我想说说我开始的想法

PHP的上传机制封装的很完全,基本几行代码就能实现,他的实现流程是这样的

UPLOAD到文件到临时目录中–>使用move_uploadde_file()到指定的目录 

这就是PHP上传流程,或者你在中途再进行一些验证。例如判断是不是通过upload方式提交的文档,或者文件的扩展是不是我们允许的

等等一系列验证。我给出简单的代码也算是抛砖引玉了。

[php]
$targetFolder = ‘/uploads’; // 定义根目录
if (!empty($_FILES)) {
$tempFile = $_FILES[‘Filedata’][‘tmp_name’];
if(is_uploaded_file($tempFile))
{
$targetPath = $_SERVER[‘DOCUMENT_ROOT’] . $targetFolder;
$targetFile = rtrim($targetPath,’/’) . ‘/’ . $_FILES[‘Filedata’][‘name’];
$fileTypes = array(‘jpg’,’jpeg’,’gif’,’png’); // 允许的后缀扩展
$fileParts = pathinfo($_FILES[‘Filedata’][‘name’]);
if (in_array($fileParts[‘extension’],$fileTypes)) {
move_uploaded_file($tempFile,$targetFile);
echo ‘1’;
} else {
echo ‘非法上传文档.’;
}
}else
{
echo "非法上传文件";
}
}
[/php]

上面的这种方式基本就满足了文件上传。但我需要的不是这样的。 继续阅读

PHP的自动化测试工具

最近一直没怎么更新博客,因为有一个很蛋疼的任务没完成。

就是做一个自动化测试工具。这工具分为单例测试和批量测试(PS:PHP程序员也开始跟测试抢饭碗了)

PS:这里说一句题外话,在项目动手之前,一定要把需求弄清楚,不然你就会像我一样,要返工N次,还不能抱怨

做接口测试,首先你要先理解两个知识点:

  1. PHP的反射(反射是PHP的一个高级应用,如果你不知道的话,那工具开发就无从下手了)
  2. CURL扩展的使用

下面分步来说明这两个小玩意多是啥?

PHP的反射(一听就知道是一个高端大气上档次的东西,因为以前都没听说过)

反射有什么用?为什么要学反射?反射的原理是什么?这一大堆因为肯定让第一次接触的你很纠结。

PHP中反射方法是Reflection。然后它的作用就是让类里面的结构明显。

这样你肯定不是很理解。我们来一个实现吧

[php]

class mysql{

public  function a(){

print_r("php中级工程师");

/**

这是一个PHP打印方法

@param string $name //输入用户名称

@param int $age //年龄

**/

private function b($name,$age)

{

echo  "你是猴子请来的逗比嘛";

}

}
}
[/php]

继续阅读

安装PHP扩展须知

其实PHP环境基本上现在分为两种:Apache和IIS(这里说的是window平台)

由于这两种调用的CGI不一样,IIS一般用的是fastcgi,而Apache一般用的ISAPI(这里说的是一般情况,你可以自己修改)

由于这两个CGI就出现了 线性安全和非线性安全 二种模式编辑的扩展(听说是这个PHP扩展开发人员就是在参照Liunx环境开发的)

简单的记住是:fastcgi 不需要线性安全检查,所以,IIS下使用fastcgi就选非线性安全扩展。反之

为什么要这样?因为IIS每次连接都会做线性安全检查,不需要PHP再去处理了。

分清了线性安全和非线性安全的问题后?有来了一个VC6和VC9两种编译区别?

VC6是什么?

VC6就是legacy Visual Studio 6 compiler,就是使用这个编译器编译的。

VC9是什么?

VC9就是the Visual Studio 2008 compiler,就是用微软的VS编辑器编译的。

那我们如何选择下载哪个版本的PHP呢?

如果你是在windows下使用Apache+PHP的,请选择VC6版本;

如果你是在windows下使用IIS+PHP的,请选择VC9版本。

就这么理解吧。挺不错的

然后,在安装PHP扩展安装不上,而且又不会报错的情况上。现在查找错误?

你需要的借鉴apache提供的错误日志。查看环境日志是一个不错的习惯。Thinkphp在运行的过程会产生一个runtime文件

里面就有程序执行记录。日志系统是很重要的查BUG和分析错误的工具。

—-

快定位出本次PHP是否为线性安全?打印出PHPinfo()

php

 

从这个字段可以看出,我安装的PH是TS 线性安全的,并且是VC11的版本。。