2006/02/21

learn:php学习笔记,语法,类与对象

tags:learn,php,php5,学习笔记,语法,类与对象
类是变量与作用于这些变量的函数的集合。
<?php
class Cart
{
var
$items ;
// 购物车中的物品

// 将 $num 个 $artnr 物品加入购物车

function add_item($artnr , $num
) {
$this->items[ $artnr] += $num
;
}

// 将 $num 个 $artnr 物品从购物车中取出

function remove_item($artnr, $num
) {
if (
$this ->items[ $artnr] > $num
) {
$this->items [$artnr] -= $num
;
return
true
;
} elseif (
$this-> items[$artnr] == $num
) {
unset(
$this ->items[$artnr
]);
return
true
;
} else {
return
false
;
}
}
}
?>
不能将一个类的定义分割到多个文件中。也不能将一个类的定义分割到多个 PHP 块中,除非该分割是在一个方法声明内部。
--不可用
<?php
class test
{
?>
<?php
function test
() {
print
'OK'
;
}
}

?>
--可用
<?php
class test
{
function
test
() {
?>
<?php
print 'OK'
;
}
}
?>
在 PHP 4 中,var 变量的值只能初始化为常量。用非常量值初始化变量,需要一个初始化函数,该函数在对象被创建时自动被调用。这样一个函数被称之为构造函数(见下面)。
class Cart {
var
$todays_date
;
var
$name
;
var
$owner
;
var
$items = array( "VCR", "TV"
);
function
Cart
() {
$this->todays_date = date("Y-m-d"
);
$this->name = $GLOBALS[ 'firstname'
];
/* etc. . . */
}
}

类也是一种类型,就是说,它们是实际变量的蓝图。必须用 new 运算符来创建相应类型的变量。
$cart = new Cart ;
伪变量 $this$this 变量可以理解为"我自己的"或者"当前对象"。
--Leonel Quinteros 09-Feb-2006 06:57
PHP Allow to extend a class in a dinamic way into a object and only affects that object not the others of the same class.
I was developing a persistence class and i found this:

<?php
class MyClass
{
var
$Prop1
;

// Into the constructor i create a propertie that was not declared before.
function MyClass
() {
$this->Prop2 = "This was not declared but now exists into the object"
;
}

function
setProp($PropName, $PropValue
) {
$this ->$PropName = $PropValue
;
}
}

$MyObj = new MyClass
();
$MyObj->setProp( "Prop1", "This was declared and now has value"
);
$MyObj-> setProp("Prop3" , "This was declared by setProp() method."
);
$MyObj->Prop4 = "This was declared out of the class definition"
;

echo
"Prop1: ".$MyObj ->Prop1. " <br />\r\n"
;
echo
"Prop2: " .$MyObj->Prop2 ." <br />\r\n"
;
echo
"Prop3: ".$MyObj ->Prop3." <br />\r\n"
;
echo
"Prop4: " .$MyObj->Prop4 ." <br />\r\n"
;

?>
This could be very useful, but very dangerous too, take care.
--Wolverine 01-Feb-2006 09:30
class Bar
{
// Constructor
function Bar
()
{
/* Some inits here */

$someval=false
;

if (
$someval=== false
)
{
$this =false
;
return;
}
}
}
$obj2=new Bar ();
// This will work as expected and return false
所以我假设 $this可以等于任何值--fallseir.lee
--Felix M dot Palmen <fmp at palmen dot homeip dot net> 10-Oct-2005 01:18
My way to implement a singleton in PHP4. I think it's the most convenient one since it works transparently using the constructor. Thanks to S.Radovanovic for his idea with referencing the class' variables, posted on http://www.php.net/manual/en/language.variables.scope.php
<?php

/* Singleton. Every instatiation returns the "same" object.
*
* for this to work, ALWAYS create objects with $object =& new class().
* The reference operator doesn't do any harm in general and is
* necessary for singletons.
*
* You also need to declare all the class' variables with "var" for
* a singleton subclass. But that should always be a rule of good
* design :)
*
* call parent::singleton() first in your subclass constructor.
*
* Of course, the subclass constructor should check if the object is already
* initialized before doing any initialization.
*/

class
singleton
{

function
singleton
()
{
// static associative array containing the real objects, key is classname
static $instances
=array();

// get classname
$class = get_class($this
);

if (!
array_key_exists( $class, $instances
))
{
// does not yet exist, save in array
$instances [$class] = $this
;
}

// PHP doesn't allow us to assign a reference to $this, so we do this
// little trick and fill our new object with references to the original
// class' variables:
foreach ( get_class_vars($class) as $var => $value
)
{
$this->$var =& $instances[ $class]->$var
;
}
}

}

?>
--Menno Vanderlist 29-Jul-2005 09:31
<?php

class
subClassA
{
//subClassA
function out
()
{
//subClassA::outA()
echo "testing subClassA\n"
;
}
}
class
subClassB
{
//subClassB
function out
()
{
//subClassB::outB()
echo "testing subClassB\n"
;
}
}
class
mainClass
{
//mainClass
var $module
;

function
mainClass ($loadModule
)
{
// load modules
eval("\$this->module = new $loadModule;"
);
}

function
out
()
{
//print out of loaded module
$this->module-> out
();
}
}
$mainA =new mainClass('subClassA'
);
$mainA-> out
();
$mainB =new mainClass( 'subClassB'
);
$mainB ->out
();
?>
outputs:
testing subClassA
testing subClassB
扩展或派生出来的类拥有其基类(这称为"继承",只不过没人死)的所有变量和函数,并包含所有派生类中定义的部分。类中的元素不可能减少,就是说,不可以注销任何存在的函数或者变量。一个扩充类总是依赖一个单独的基类,也就是说,不支持多继承。使用关键字"extends"来扩展一个类。
class Named_Cart extends Cart {
var
$owner
;

function
set_owner ( $name
) {
$this ->owner = $name
;
}
}
get_class( $this)
get_parent_class( $this)
parent ::two();//call parent method,inner class
$one->two();//call parent method,object
--doedje12-Feb-2006 01:37
class a
{
function
showInfo
()
{
print
"I am class " . get_class($this ) . ", my parent is " . get_parent_class($this
);
}
}

class
b extends a
{}

class
c extends b
{}

$myInstanceB = new b
();
$myInstanceB->showInfo
();
print
"<br />"
;
$myInstanceC = new c
();
$myInstanceC-> showInfo
();

/*
output:
I am class b, my parent is a
I am class c, my parent is b
*/
构造函数是类中的一个特殊函数,当使用 new 操作符创建一个类的实例时,构造函数将会自动调用。当函数与类同名时,这个函数将成为构造函数。如果一个类没有构造函数,则调用基类的构造函数,如果有的话。
也可以使用 @ 操作符来抑制发生在构造函数中的错误。例如 @new
类 A 中的函数 B() 将立即成为类 B 中的构造函数,虽然并不是有意如此。PHP 4 并不关心函数是否在类 B 中定义的,或者是否被继承来的。
PHP 4 不会从派生类的构造函数中自动调用基类的构造函数。恰当地逐次调用上一级的构造函数是用户的责任。
析构函数是一种当对象被销毁时,无论使用了 unset() 或者简单的脱离范围,都会被自动调用的函数。PHP 中没有析构函数。可以用 register_shutdown_function() 来替代模拟大多数析构函数的效果。
--dexen at NOSPAM dot example dot com 18-Jan-2006 02:44
<?php
class ExObject
{

function
_FINI_
()
{
$p = get_class($this
);
while(
$p
) {
$px = '_'. $p.'_'
;
if (
method_exists($this , $px
) ) {
$this->$px
();
}
$p = get_parent_class ( $p
);
}
}
}
?>
有时,在没有声明任何实例的情况下访问类中的函数或者基类中的函数和变量很有用处。而 :: 运算符即用于此情况。
A::example ();
类 B 重新定义了函数 example()。A 类中原始定义的函数 example() 将被屏蔽并且不再生效,除非使用 :: 运算符来访问 A 类中的 example() 函数。如:A::example()(实际上,应该写为 parent::example(),
不要用代码中基类文字上的名字,应该用特殊的名字 parent,它指的就是派生类在 extends 声明中所指的基类的名字。这样做可以避免在多个地方使用基类的名字。如果继承树在实现的过程中要修改,只要简单地修改类中 extends 声明的部分。
在 PHP 3 中,在序列化和解序列化的过程中对象会失去类的关联。结果的变量是对象类型,但是没有类和方法,因此就没什么用了(就好像一个用滑稽的语法定义的数组一样)。
serialize() 返回一个字符串,包含着可以储存于 PHP 的任何值的字节流表示。 unserialize() 可以用此字符串来重建原始的变量值。用序列化来保存对象可以保存对象中的所有变量。对象中的函数不会被保存,只有类的名称。
要能够 unserialize() 一个对象,需要定义该对象的类。也就是,如果序列化了 page1.php 中类 A 的对象 $a,将得到一个指向类 A 的字符串并包含有所有 $a 中变量的值。如果要在 page2.php 中将其解序列化,重建类 A 的对象 $a,则 page2.php 中必须要出现类 A 的定义。例如可以这样实现,将类 A 的定义放在一个包含文件中,并在 page1.php 和 page2.php 都包含此文件。
$s = serialize ($a);
$a = unserialize( $s);
serialize() 检查类中是否有魔术名称 __sleep 的函数。如果这样,该函数将在任何序列化之前运行。它可以清除对象并应该返回一个包含有该对象中应被序列化的所有变量名的数组
使用 __sleep 的目的是关闭对象可能具有的任何数据库连接,提交等待中的数据或进行类似的清除任务。此外,如果有非常大的对象而并不需要完全储存下来时此函数也很有用。
相反地,unserialize() 检查具有魔术名称 __wakeup 的函数的存在。如果存在,此函数可以重建对象可能具有的任何资源。
使用 __wakeup 的目的是重建在序列化中可能丢失的任何数据库连接以及处理其它重新初始化的任务。
在构造函数中创建引用可能会导致混淆的结果。
$globalref[] = &$this ;
"new"默认并不返回引用,而返回一个拷贝
$bar1 = new Foo ('set in constructor');
//$globalref[0]和$bar1指向不同的地址
$bar2 =& new Foo( 'set in constructor');
//$globalref[1]和$bar2指向相同的地址



对象的比较

在 PHP 4 中,对象比较的规则十分简单:如果两个对象是同一个类的实例,且它们有相同的属性和值,则这两个对象相等。类似的规则还适用与用全等符(===)对两个对象的比较。







--
[:p] --飞扬.轻狂 [fallseir.lee]
http://fallseir.livejournal.com
http://feed.feedsky.com/fallseir

没有评论: