php类型约束
函数的参数可以指定为对象、数组,注意,即使使用了类型约束,如果使用null作为参数的默认值,那么在调用函数的时候可以使用mull作为实参
例子
<?php
Class MyClass{
public function test(OtherClass $otherclass){
echo $otherclass->var;
}
public function testArray(array $input_array){
print_r($input_array);
}
}
class OtherClass{
public $var='hello';
}
$myclass=new MyClass();
$otherclass=new OtherClass();
$myclass->test('hello');//Argument 1 passed to MyClass::test() must be an instance of OtherClass 参数必须是类otherclass的一个对象
$foo=new subClass();
$myclass->test($foo);//Argument 1 passed to MyClass::test() must be an instance of OtherClass 参数必须是类otherclass的实例
$myclass->test(null);// Argument 1 passed to MyClass::test() must be an instance of OtherClass, null given 参数不能为空
$myclass->test($otherclass);//hello
$myclass->testArray('hello');//Argument 1 passed to MyClass::testArray() must be an array, string given 参数必须是array
$myclass->testArray(array('a','v','d'));// Array ( [0] => a [1] => v [2] => d )
?>
因此:函数调用的参数与定义的参数类型必须一致
另外注意:
1..类型约束允许null值
2.类型约束只支持对象和数组
3.针对接口和抽象类的参数
<?php
interface fooface
{
public function foo ();
}
class fooclass implements fooface
{
public function foo ()
{
echo ('foo<br>');
}
}
class barclass implements fooface
{
public function foo ()
{
echo ('bar<br>');
}
}
class bazclass implements fooface
{
public function foo ()
{
echo ('baz<br>');
}
}
class quuxclass
{
public function foo ()
{
echo ('quux<br>');
}
}
function callfoo (fooface $myClass)
{
$myClass -> foo ();
}
$myfoo = new fooclass;
$mybar = new barclass;
$mybaz = new bazclass;
$myquux = new quuxclass;
callfoo ($myfoo);//foo
callfoo ($mybar);//bar
callfoo ($mybaz);//baz
callfoo ($myquux); // Argument 1 passed to callfoo() must implement interface fooface
?>
php引用
php引用是别名,就是两个不同的变量名字指向相同的内容,在php5,一个对象变量已经不再保存整个对象的值,只是保存一个标示符来访问真正的对象内容,当对象作为参数传递,最为结果返回,或者赋值给另一个变量,另一个变量跟原来的不是引用的关系,只是他们都保存着同一个标示符的拷贝,这个标示符指向同一个对象的真正内容
<?php
class A {
public $foo = 1;
}
$a = new A;
$b = $a; // $a ,$b都是同一个标识符的拷贝
// ($a) = ($b) = <id>
$b->foo = 2;
echo $a->foo."\n";
$c = new A;
$d = &$c; // $c ,$d是引用
// ($c,$d) = <id>
$d->foo = 2;
echo $c->foo."\n";
$e = new A;
function foo($obj) {
// ($obj) = ($e) = <id>
$obj->foo = 2;
}
foo($e);
echo $e->foo."\n";
?>
打印结果是:2 2 2
例子2
<?
class Foo {
private static $used;
private $id;
public function __construct() {
$id = $used++;
}
public function __clone() {
$id = $used++;
}
}
$a = new Foo; // $a is a pointer pointing to Foo object 0
$b = $a; // $b is a pointer pointing to Foo object 0, however, $b is a copy of $a
$c = &$a; // $c and $a are now references of a pointer pointing to Foo object 0
$a = new Foo; // $a and $c are now references of a pointer pointing to Foo object 1, $b is still a pointer pointing to Foo object 0
unset($a); // A reference with reference count 1 is automatically converted back to a value. Now $c is a pointer to Foo object 1
$a = &$b; // $a and $b are now references of a pointer pointing to Foo object 0
$a = NULL; // $a and $b now become a reference to NULL. Foo object 0 can be garbage collected now
unset($b); // $b no longer exists and $a is now NULL
$a = clone $c; // $a is now a pointer to Foo object 2, $c remains a pointer to Foo object 1
unset($c); // Foo object 1 can be garbage collected now.
$c = $a; // $c and $a are pointers pointing to Foo object 2
unset($a); // Foo object 2 is still pointed by $c
$a = &$c; // Foo object 2 has 1 pointers pointing to it only, that pointer has 2 references: $a and $c;
const ABC = TRUE;
if(ABC) {
$a = NULL; // Foo object 2 can be garbage collected now because $a and $c are now a reference to the same NULL value
} else {
unset($a); // Foo object 2 is still pointed to $c
}
?>
对象的序列化
在所用的php里面的值都可以使用serialize()来返回一个包含字节流的字符串来表示,unserialize()函数能够重新把字符串变回php原来的值,序列化一个对象将会包存对象的所用的变量,但是不会保存对象方法,值保存类的名字
为了能够unserialze()一个对象,这个对象的类必须已经定义过,如果序列化类A的一个对象,将返回一个跟类A相关,而且包含了对象所有变量值的字符串,如果要想在另一个文件中解序列化一个对象,这个对象的类必须在解序列化之前定义,可以通过包含一个定义该类的文件或使用函数spl_autoload_register()实现
<?php
// classa.inc:
class A {
public $one = 1;
public function show_one() {
echo $this->one;
}
}
// page1.php:
include("classa.inc");
$a = new A;
$s = serialize($a);
// 把变量$s保存起来以便文件page2.php能够读到
file_put_contents('store', $s);
// page2.php:
// 要正确了解序列化,必须包含下面一个文件
include("classa.inc");
$s = file_get_contents('store');
$a = unserialize($s);
// 现在可以使用对象$a里面的函数 show_one()
$a->show_one();
?>
当一个应用程序使用函数session_register()来保存对象到会话中时,在每个页面结束的时候这些对象都会自动序列化,而在每个页面开始的时候又自动解序列化。 所以一旦对象被保存在会话中,整个应用程序的页面都能使用这些对象。但是,session_register()这个函数在php5.3.0已经废弃,而且在php6.0.0就不再支持,所以不要依赖这个函数。
在应用程序中序列化对象以便在之后使用,强烈推荐在整个应用程序都包含对象的类的定义。 不然有可能出现在解序列化对象的时候,没有找到该对象的类的定义,从而把没有方法的类__PHP_Incomplete_Class_Name作为该对象的类,导致返回一个没有用的对象。
所以在上面的例子中,当运行session_register("a"),把变量$a放在会话里之后,需要在每个页面都包含文件classa.inc,而不是只有文件page1.php和page2.php。