2011-03-06

PHP中静态调用非静态方法

类归于: PHP — 标签:, maker @ 20:52

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毫秒之间,这样看来,静态调用非静态方法的效率要比标准的静态方法调用低的多,所以在效率上也不推荐静态调用非静态方法

2010-05-25

仿symfony机制实现不用require或者include来实例化类

类归于: PHP, symfony — 标签:, kthiz2006 @ 10:35


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

2010-05-24

vim配合phpcs实现自动语法检查

类归于: PHP, vi/vim — 标签:, , , , maker @ 10:40

在开发过程中, 我们需要保证语法正确, 当然这是基础, 也是必须做到的. 很多时候, 我们还要去遵守一些编码规范, 比如PEAR规则, Zend规则等等, 这样可以让我们写出清晰并且容易阅读的代码, 但是通常来说, 自觉遵守规范是一个很难办到的事情, 所以我们可能需要借助一些辅助方法.

Vim是一款很强大的编辑器, 拥有着可谓无所不能的扩展机制, 这里我简单介绍一下Vim配合phpcs实现自动和手动的语法检查.

什么是phpcs?

phpcs全名PHP_CodeSniffer, 是PEAR中一个用来检测PHP代码规范的包, 他是确保你代码简介一致的必不可少的工具, 并且可以更快的帮你找到语法错误. 关于phpcs的具体安装和使用方法这里就不做说明了, 请各位读者自行查找.

注: phpcs中默认提供了一些编码规范, 在开发过程中我们可能需要一些自己的规范, 可以在phpcs的目录中添加新规范, 规范的编写方法请参考一些内置规范, 规则都是phpcs已经有的, 只需修改声明就可以了.

我们需要扩展vim的功能, 这样需要编写一些脚本, 脚本可以直接加到你的vim配置文件中, 也可以保存成脚本保存在$VIMHOME/plugin/目录下.

下面是脚本内容:

function! Phpcs()
" phpcs 命令的路径和参数, 请根据环境自行修改
! /home/bobhero/Dropbox/project/libphp/bin/phpcs --standard=Zend "%"
cwindow
endfunction
" :w 自动验证语法
autocmd BufWritePost *.php call Phpcs()
" :Phpcs 验证语法
command! Phpcs execute Phpcs()

以上代码添加完毕后重启vim, 然后你就可以在保存文件(:w)的同时自动检查语法了, 还可以在vim中调用Phpcs命令(:Phpcs 注意区分大小写), 我在网上还看见了一些更强大的脚本, 这里就不详细介绍了.

2010-05-21

symfony1.4 DateTime对于PHP低版本的兼容问题

类归于: symfony — 标签:, szn000 @ 13:17

在symfony1.4中使用DateTime 类 但是该类出现于 PHP 5.2.0以后 所以在使用(部分方法需要在PHP5.3.0以后版本才能使用)PHP5.2.0以前版本的服务器上 调用symfony调用该函数会出错 为了解决该类问题根据 PHP5.2.0 的DateTime类 写了俩个类 用以在低版本中使用该类
以重写方法
DateTime.class.php
__construct ([ string $time = "now" [, DateTimeZone $timezone = NULL ]] )
string format ( string $format )
int getOffset ( void )
int getTimestamp ( void )
DateTimeZone getTimezone ( void )
DateTime setDate ( int $year , int $month , int $day )
DateTime setISODate ( int $year , int $week [, int $day = 1 ] )
DateTime setTime ( int $hour , int $minute [, int $second = 0 ] )
DateTime setTimestamp ( int $unixtimestamp )
DateTime setTimezone ( DateTimeZone $timezone )
DateTime __wakeup ( void )

DateTimeZone.class.php
__construct ( string $timezone )
string getName ( void )
int getOffset ( DateTime $datetime )

文件下载地址: 下载点击我
附件使用时把类名中的My删除

2010-05-17

使用Bit.ly短网址服务API简化URL

类归于: PHP — 标签:, , maker @ 10:16

最近项目中涉及到Tw***er, 需求要使用PHP更新Tw***er中的状态, 自动加上链接地址并且链接地址要通过bit.ly进行简化.

什么是Bit.ly?

Bit.ly是一个短网址服务, 根据原网址生成一个新的较短的网址, 由于微博客发言有字数限制, 所以短网址服务在微博客中广为应用.

使用PHP调用bit.ly api有很多方法, 这里只简单提供一个例子, 详细文档和例子请登陆http://bit.ly自行查找.

使用bit.ly api首先要注册一个账户, 注册完之后会得到一个api key, 有了api key我们才能合法使用bit.ly的api, api key在个人资料中.下面是txt格式调用api的函数.

注: 打开url读取内容需要开启php的allow_url_fopen选项.

function make_bitly_url ($url, $login = 'm4ker',
$api_key = 'R_04354c1e3500db9f43f1fedaf234****') {
return file_get_contents(
'http://api.bit.ly/v3/shorten?login='.$login
.'&apiKey='.$api_key
.'&uri='.urlencode($url)
.'&format=txt');
}

早前文章 »

WordPress 所驱动