PHP核心技术——魔术方法
2024-09-27 18:15:30
魔术方法:
- 魔术方法是以两个下画线开头、具有特殊作用的一些方法,可以看做PHP的“语法糖”。
set和get方法:
class Account{
private $user=1;
private $pwd=2;
public function __set($name,$value)
{
echo "Setting".$name." to ".$value."\r\n";
$this->$name=$value;
}
public function __get($name)
{
if (!isset($this->$name)) {
echo "not default";
$this->$name="setting default";
}
return $this->$name;
}
}
$a=new Account();
echo $a->user;
echo "-----------\n";
$a->name=5;
echo $a->name;
echo "-----------\n";
echo $a->big;
- 而PHP则在一个类中只允许有一个构造函数
- PHP提供的“重载”指动态地“创建”类属性和方法。因此,set和get方法被归到重载里。
call和callStatic方法:
- 当调用一个不可访问的方法(如未定义,或者不可见)时,call()会被调用。其中name参数是要调用的方法名称。arguments参数是一个数组,包含着要传递给方法的参数
class callFun
{
public function __call($name,$arguments)
{
switch (count($arguments)) {
case 2:
echo $arguments[0]*$arguments[1],PHP_EOL;
break;
case 3:
echo array_sum($arguments),PHP_EOL;
break;
default:
echo 'wrong',PHP_EOL;
break;
}
}
}
$a =new callFun;
$a->make(5);
$a->make(5,6);
- 这段代码通过使用callStatic这一魔术方法进行方法的动态创建和延迟绑定,实现一个简单的ORM模型。
abstract class ActiveRecord{
protected static $table;
protected $fieldvalues;
public $select;
static function findById($id){
$query="select * from ".static::$table." where id=".$id;
return self::createDomain($query);
}
function __get($fieldname){
return$this->fieldvalues[$fieldname];
}
static function __callStatic($method,$args){
$field=preg_replace('/^findBy(\w*)$/','${1}',$method);
$query="select * from ".static::$table." where ".$field."=".$args[0];
return self::createDomain($query);
}
private static function createDomain($query){
$klass=get_called_class();
$domain=new $klass();
$domain->fieldvalues=array();
$domain->select=$query;
foreach($klass::$fields as $field=>$type){
$domain->fieldvalues[$field]='TODO:set from sql result';
}
return $domain;
}
}
class Customer extends ActiveRecord{
protected static $table='custdb';
protected static $fields=array(
'id'=>'int',
'email'=>'varchar',
'lastname'=>'varchar'
);
}
class Sales extends ActiveRecord{
protected static $table='salesdb';
protected static $fields=array(
'id'=>'int',
'item'=>'varchar',
'qty'=>'int'
);
}
assert("select * from custdb where id=123"==Customer::findById(123)->select);
assert("TODO:set from sql result"==Customer::findById(123)->email);
assert("select * from salesdb where id=321"==Sales::findById(321)->select);
assert("select * from custdb where Lastname='Denoncourt'"==Customer::findByLastname('Denoncourt')->select);
toString方法:
- 当进行测试时,需要知道是否得出正确的数据。比如打印一个对象时,看看这个对象都有哪些属性,其值是什么,如果类定义了toString方法,就能在测试时,echo打印对象体,对象就会自动调用它所属类定义的toString方法,格式化输出这个对象所包含的数据。如果没有这个方法,那么echo一个对象将报错,例如“Catchable fatal error:Object of class Account could not be converted to string”语法错误,实际上这是一个类型匹配失败错误。不过仍然可以用print_r()和var_dump()函数输出一个对象。当然,toString是可以定制的,所提供的信息和样式更丰富。
class Account
{
public $user=1;
private $pwd=2;
//自定义的格式化输出方法
public function __toString()
{
return "{$this->user}, {$this->pwd}";
}
}
$a = new Account();
echo $a;
echo PHP_EOL;
print_r($a);
参考资料
- [PHP核心技术与最佳实践]
最新文章
- 学习Struts2的第一个应用步骤
- maven 环境搭建
- MYSQL 的错误Incorrect information in file: '.\test\stuff.frm
- oracle 常用语法
- iOS- NSDateFormatter (自定义时间格式)
- 10046事件跟踪会话sql
- ps里面的批处理教程
- 在英文 sql2005中 比较nvarchar 与 varchar的速度
- HTML&;CSS基础学习笔记1.27-input提交数据
- GIT 实验
- Java程序员常犯的10个错误
- myeclipse 的Customize Perspective 没有反应
- SonarQube(代码质量管理)配置与使用
- 纯js上传文件 很好用
- Java并发(六)线程池监控
- BloodHound官方使用指南
- 你真的理解js的赋值语句么
- iOS开发——iOS7(及以后版本) SDK自带二维码(含条形码)扫码、二维码生成
- 新手学ajax2
- mysql自学路线