显示标签为“PHP”的博文。显示所有博文
显示标签为“PHP”的博文。显示所有博文

2007-03-26

PHP4.4.6和Mysql 5.0

请访问:
http://shiningray.cn/2007/03/26/php446mysql50/

2006-10-04

PHP怪现象[5]

这次要说的是PHP5中的一种叫做type hinting(类型暗示)的东西,从使用上来说,接近于Java这类静态类型的类型检查,比如:

<?
interface A{
function a();
}
class AA implements A{
public function a(){
print "A";
}
}
function b(A $a){
$a->a();
}
?>

如果现在运行b(new AA());则会顺利通过,输出一个A,而使用任何其他类型的,比如b(new stdClass());b(1);b("a");之类的,都会出现这种错误:Fatal error: Argument 1 passed to b() must implement interface A, called in ....
应该说,这东西确实给OOP中的类型检测带来了福音,我们无须写if(xx instanceof xxx)这类繁琐的判断语句了。不过,这功能也有点鸡肋的嫌疑。原因有三:

  1. PHP是动态类型的,又是弱类型的,这种type hinting只是虚拟机层次上的动态类型判断,即不能做到编译时提前检查出一些类型错误,也不能给予性能上的极大的提升,
  2. 无法处理基本类型,如string, int——如果将这些东西应用在这个位置上(不过PHP5.1开始array也可以,真是很奇怪),PHP会检查有没有叫做string、int的类或接口;而同样具有type hinting的perl 6,则作的相对更好,比如Perl 6中至少可以将type hinting应用于基本类型上
  3. 不能进行函数重载,如果实现了的话,PHP可能就变成Generic Programming了,但对于PHP这种动态语言来说,这并不是必要的,但现在又具备了type hinting,为何却不能根据类型来进行一些推断(type inference)呢?

2006-09-19

Perl复习

我在高中的时候曾经学习过一段时间的Perl,是为了给“宇宙工作室” 制作一个下载站点,为了找一个动态的免费空间可不容易啊,当时是51.net提供了免费的cgi空间,支持Perl,于是乎,特地学习了Perl,并在网上寻找了一个免费的代码改了一遍,
时过6年,又想重新学习Perl——毕竟是一个风靡一时的语言,而且其CPAN中丰富的包,也是相当实用的。
话又说回来,时过六年,Perl6也没有推出,实在是一个遗憾。
从大学开始学习了PHP,PHP从Perl中借鉴了很多东西,比如$式的变量,但实际上和Perl还是有很大区别的,之前我曾经翻译过一篇PHP 对比 PERL,从中可以看出很多不同的地方。
比如,其实Perl是一个函数式编程语言,有词法范围。
关于具体的细节,我会整理一个表格列出来,希望对其他学习两者的朋友有所帮助。

2006-09-16

PHP之怪现象[3]

这次要说的怪现象在于PHP的性能问题,且不说PHP的性能有多差,因为毕竟是一个脚本语言,不能奢望其速度多快,但PHP的性能的奇怪问题确实很特别:

  1. 版本的提升并未带来性能的提升——PHP5比PHP4慢
  2. 通过一些字节码优化器来大幅度提高性能
关于第一点,可以看一些对比(数据来自http://byster.net/):


PHP: version 4.3.10 vs PHP: version 5.0.5
PC: Celeron 2.0Mhz / 512Mb

PHP 4 PHP 5

Creating int array[100 000]

for vs while
code
[ms]
for($i=0;$i<10000;$i++)0.0630.087
while($i<10000)>0.0570.086

Reading int array[100 000]

while vs foreach vs or
foreach($arr1 as $vl) {..} 0.0850.171
while(list(,$vl) = each($arr2)) {..} 0.2610.335
for($i=0;$i<10000;$i++)0.1230.163

Reading apache log (16Mb)

file vs file_get_content vs fread
$a = file("t1.log");0.2700.274
$b = file_get_contents("t1.log");0.1200.121
.. $c = fread($hdl, $size); .. 0.1330.141

Parse vars names [100 000]

"test$i" vs "test".$i vs ‘test’.$i
for(…) {$c = "test$i";}0.3160.354
for(…) {$c = "test".$i;}0.2050.236
for(…) {$c = ‘test’.$i;}0.2050.236

Parse and find text from apache log (32Mb)

ereg vs preg_match
eregi("2005:03:04",$txt);3.5043.521
preg_match("/2005:03:04/im",$txt);0.1080.735

Split text apache log 200Kb (contain 2000 "-")

split vs explode
split("-",$txt);1.5611.573
explode("-",$txt);0.1930.197

Count array size. $arr = int[100 000]

count vs sizeof
for($i=0;$i<count($arr);$i++)0.1980.276
for($i=0;$i<sizeof($arr);$i++)0.1980.268

Create object by Ref (loop 100 000)

with ref vs without ref
(…) {$j = & new TestClass();}0.4601.180
(…) {$j = new TestClass(); }0.4701.291

Random number generator (loop 100 000)

srand vs mt_srand
(…) { srand(); } 0.1850.193
(…) { mt_srand(); } 0.9290.989

Calculate hash (loop 100 000)

srand vs mt_srand
(…) { md5($i."byster.net".$i); } 1.3061.365
(…) { sha1($i."byster.net".$i);}1.4921.662
至于第二点,其实也不用多说了,Zend Encoder、Zend Optimizer、eAccelerator、APC等等,而不得不提的是 ,经过Zend Encoder过的PHP代码,只能在有Zend Encoder或者Zend Optimizer的情况下才可以运行,而Zend Encoder是个商业软件。

2006-09-15

PHP之怪现象(2)

在前面一篇文章PHP之怪现象 中,说到了array()是值复制而非引用的,那么要使用引用的数组,要怎么办呢,PHP5引入的奇特的Standard PHP Library
其中有一个ArrayObject,可以实现引用的数组:
$a = array(1,2,3);
$arrobj = new ArrayObject($a);
这样就可以得到一个行为基本和原始array()一样的一个ArrayObject实例,你也可对其进行foreach操作,不过和基本的array()有一些区别:

  1. 大多数array相关的函数不能使用,如count(),必须使用ArrayObject的count()方法,象array_push() array_pop()等则无法使用
  2. 对ArrayObject使用[]取出某个值的时候,如$arrobj['a'],如果要对这个值进行处理如--、++、[]=等操作,不能使用链式表达式,必须先将这个值取到某个变量中才能使用,如下是错误的:
    $arrobj[1]++; $arrobj[0]--; $arrobj[2][0] = 1;

  3. ArrayObject的性能比array()的性能差很多,慢一倍多点

说完了ArrayObject,还要说一下和ArrayObject密切相关的另一个东西ArrayIterator,一个数组的迭代器。很难说明SPL的目的到底是什么。下面先看看SPL的一张类图



如此复杂的类图,第一眼看,觉得很象Java,但PHP没有OOP中万物之本的Object类(其实如果用类型转换的object转换,是可以得到一个奇怪的stdClass的实例,但没人知道这是干什么用的),如果说是像C++,又少了GP的支持,而PHP低下的运行效率――不要说和Java比,就是和Lua比,也差太多了,谁敢使用这么庞大复杂的类库呢?

2006-09-14

PHP之怪现象

下面总结一些我发现的PHP的奇怪事情:

1.array()并非引用类型
array()并非一个对象的构造函数,它是一个语言结构,它返回的虽然是一个结合数组,但并非一个对象,即时在所谓OO的PHP5中,也是有问题的:
$a = array(...);
$b = $a;
print $b === $a;
这时候,确实输出为1,表示两者一致,PHP的手册上是这么说的:
$a == $b 相等 如果 $a 和 $b 具有相同的键/值对则为 TRUE
$a === $b 全等 如果 $a 和 $b 具有相同的键/值对并且顺序和类型都相同则为 TRUE
所以,===对于对象来说,才是同一性比较
如果这时修改$b的某个值,那么$b就和$a不等了
$b[0] = 5;
print $b === $a;
这时什么也不输出,表示为false
如果要获取$a的引用,必须强制性地使用&操作符
$b =& $a;
由此引出了2

2. foreach和each()等数组操作

foreach($arr as $k => $v)表示遍历$arr中的每个元素$e,同样的,这个$v是=出来的,相当于$arr[$k] = $v,而非$arr[$k] =& $v,并非$arr中的实际元素,那就有两种情况:
  1. $arr[$k]这个元素正好是一个对象,这时其中存储的其实是一个引用,那么$v可以正确指向最终的对象
  2. 之外所有的类型,都是一个副本,如果是一个数组,那么是数组的副本
因此,如果要实际改变$arr中的元素,应当使用$arr[$k],而非$v。
这种问题同样可出现在其他数组操作,each(),current()等。
2. include和eval
include和eval哪个快?
答案是eval快,这个确实比较奇怪,即使算上文件操作,纯粹执行代码,eval(file_get_contents($file))要比include快那么一点。
问题可能在于include要处理<?php ?>这些东西,而eval仅处理php代码。
其它的以后再慢慢总结