1.PHP中可以静态调用非静态方法么?
今天我被问到PHP中可不可以使用 className::methodName() 的方法来调用一个没有声明Static的方法。在我的印象中,我好像是见过这种用法,但又有些不确定。大家都知道,在手册或者教程里,方法被分为静态方法和非静态方法,通常我们静态调用的方法,肯定是静态方法。
那如果我们调用了非静态方法会怎么样呢?首先做测试.
<?php
class test{
function test(){
echo 'it works';
}
}
test::test();
执行以下,返回错误如下
Fatal error: Non-static method test::test() cannot be called statically in /home/×××/test.php
on line 7 Call Stack: 0.0002 332548 1. {main}() /home/×××/test.php:0
这个时候,可能大家就会认为静态调用非静态方法是行不通的了,但其实,结论下的过早了,因为test()这个方法比较特殊,与类同名,是构造方法。
我们继续测试。
<?php
class test{
function test(){
echo 'it works';
}
function test2(){
echo 'it works too';
}
}
test::test2();
执行结果:
it works too
这说明,静态调用非静态方法是可行的,但是静态调用构造方法是不可以的。为了验证这个结论,我又做了如下测试:
<?php
class test{
static function test(){
echo 'it works';
}
}
test::test();
执行的结果如下:
Fatal error: Constructor test::test() cannot be static in /home/xxx/test.php on line 9
构造方法不能声明静态,所以上面的推论正确。
但这个结果的确是很特殊的,因为可能只有PHP可以静态调用非静态方法,我用Java做了实验,如果静态调用非静态方法会报如下错误:
Cannot make a static reference to the non-static method showString() from the type HelloWorldApp
其他语言我没有一一尝试,但这已经足够来说明PHP的特殊之处,关于为什么PHP会有这样的情况我暂时没有找到相关说明。
2.静态调用非静态方法是否应该被应用?
那我们是不是可以使用这种方法来代替static方法呢? 首先在代码的可读性上来看,静态调用非静态方法当然是不被推荐的,这会让维护者产生疑惑。
接下来我们再做一些实验,来看一下静态调用非静态方法在效率上是否会有一定的优势。
<?php
class test{function test2(){}}
for($k=0; $k<10000; $k++)
{
test::test2();
}
上面代码在我这里的执行时间是18到28毫秒,我们再来测试标准的写法。
<?php
class test{static function test2(){}}
for($k=0; $k<10000; $k++)
{
test::test2();
}
上面的代码执行时间在5到10毫秒之间,这样看来,静态调用非静态方法的效率要比标准的静态方法调用低的多,所以在效率上也不推荐静态调用非静态方法。
由于种种原因,本站的symfony系列教程已经停止更新一年之久,又因种种原因,本站的编辑们也都停止了对本站的维护。
symfony是我使用过最经典的php框架,symfony可能不是最好的,但在我用过的种种框架中,symfony绝对是最优秀的,虽然,我现在已经连创建项目的命令都已经忘掉了,但是symfony的oo思想让我获益匪浅。
目前symfony的2.0版本已经在开发阶段,国内的symfony开发者也越来越多,本站绝大多数的symfony文章都是1.2版本的时候写的,可能已经跟不上时代,但其中的思想仍然值得广大symfony入门者参考,我对本站的symfony文章进行了一次整理,很遗憾没能把这些文章写成一个系列。
基础篇
进阶篇
高级篇
在此感谢站长bobhero和每一位做出过贡献的编辑们(排名不分先后)zhuozi,kthiz2006,hansir,szn000,duandi,同时也感谢各位读者对我们的支持。
工作中,遇到一个问题 ,同样的代码在FIREFOX 和 IE 下 表现 相差太多 ,查之 ,竟然是因为 session_id() 返回值的问题,解决过程如下
1. 测试 FIREFOX 和 IE ,IE每次刷新页面时 得到的SESSION_ID 值不一样,FIREFOX 一样
2.测试 IE6,IE7,IE8 竟然 只有IE7 有这种 现象………..
3.经多方查证,没有结果 ,网上没有人和我的情况一下,自己解决吧
4.我左三圈右三圈 ,最后发现 竟然 是 内裤 掉色 ……………………………………………………………
域名里 有 下线 “_” ,这个竟然 是BUG 所在点
结论: 在IE7 下 ,如果 域名里包括下划线,SESSION 将失效
如果你觉得本BLOG对你有帮助 ,请帮助其它人
这是一个过滤URL中 多个’/'的例子
修改 apps/myapp/config/filters.yml
添加代码
myFilter:
class: myFilter
(myFilter可自定义)
创建文件myFilter.class.php
创建位置apps/myapp/lib/
文件内容如下
使用preg_match 是因为 ereg 过时
注意preg_match 匹配正则时以’/'开始和结束
class myFilter extends sfFilter
{
public function execute ($filterChain)
{
//提取uri
$str = $_SERVER['REQUEST_URI'];
//判断是否匹配正则
if(preg_match("/(.*\/{2,}.*)((\.html)*)/",$str)){
//要跳转的页面
header("Location:/error.html");
//跳转后代码不执行
exit();
}
//执行下一个filter
$filterChain->execute();
}
}
修改apps/myapp/config/routing.yml
添加代码 此代码用来定义URL /error.html 要执行的模块和动作
Error:
url: /error.html
param: { module: index, action: error404}
class MyClass {
public static function register() {
//如果解串行器发现有未定义类要被实例化,则设置spl_autoload_call函数加载请求类.
ini_set('unserialize_callback_func', 'spl_autoload_call');
//自动载入类,类似于__autoload
if (false === spl_autoload_register(array("MyClass","autoLoad"))) {
throw new Exception('wrong');
}
}
//处理自动载入类
public static function autoload($className) {
require realpath(dirname(__FILE__)).'/lib/'.strtolower($className).'.class.php';
}
}
只要在项目目录中创建一个类的目录,这里我创建的叫lib,往这里放入你要放的类的文件。
注:
1.类的文件名要统一规则,这样方便系统快速地进行查找,避免消耗更多的内存。
2.autoload的函数的载入类的规则可以依据需要进行设置,我这里规定要载入我的lib目录里文件的扩展名是class.php的类的文件。
以下是使用的例子:
在创建的lib目录里方了一个叫cache的类的文件。
接着在你要编写的程序文件里载入上边的说的自动载入类的文件,使用MyClass::register(),就可以不用载入要实例化的类的文件直接实例化刚才的cache的类的文件。
以上说的实现的效果必须是php的版本>=5.1.2