php php常用构造函数数

没有更多推荐了,
不良信息举报
举报内容:
PHP 构造方法 __construct()
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!php面向对象之构造函数作用与方法-php教程-PHP中文网QQ群微信公众号还没有收藏php面向对象之构造函数作用与方法什么是构造函数呢?构造函数又有什么作用呢?构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。可能上面的描述大家还是不能很清楚的了解,我们就举例子向大家讲解下。构造函数的用法实例我们先创建一个类,并且初始化这个类。class Preson{
//定义变量
$Preson1 = new Preson();
$Preson1-&$name = &大白&;
//变量赋值
$Preson1-&$age = 20;
$Preson1-&$sex = &女&;
$Preson1-&$height = 180;可以看到,上述例子中赋值过程比较繁琐,如果变量很多的话,工作量将会非常大,很麻烦。所以,我们引入了构造方法。所以构造函数的作用就是用来初始化对象的。该方法可以没有参数,也可以有多个参数。定义构造函数也很简单,__construct(),值得注意的是函数construct前面是两个下划线&_&.了解了构造函数之后,我们用构造函数来重写上面的例子:class Preson{
//定义变量
function __construct($name,$age,$sex,$height){
$this-&name = $
//为变量赋值
$this-&age = $
$this-&sex = $
$this-&height = $
public function PlayBaskteBall(){
if($this-&height&175 || $this-&age & 22){
$this-&name . &可以打篮球&;
return $this-&name . &不具备打球的条件&;
$Preson1 = new Preson(&大白&,&20&,&女&,&180&);
echo $$Preson1-&PlayBaskteBall();构造方法是初始化对象时使用的,如果没有构造方法,那么PHP会自动生成一个。自动生成的构造方法没有任何参数,没有任何操作。以上就是php面向对象之构造函数作用与方法的详细内容,更多请关注php中文网其它相关文章!共3篇713点赞收藏分享:.php.cn&猜你喜欢PHP中文网:独家原创,永久免费的在线,php技术学习阵地!
All Rights Reserved | 皖B2-QQ群:关注微信公众号5.1构造函数问题 - ThinkPHP框架
protected $beforeActionList = [
'first',
//---------------------------------------------
protected $auth_
protected $auth_
protected $
//------------5.0版本可以用------5.1 parent::__construct();报错-----------------
function __construct() {
parent::__construct();
$this-&auth_rule=new \app\common\model\AuthRule();
$this-&auth_group=new \app\common\model\AuthGroup();
$this-&admins=new \app\common\model\Admins();
//------------5.1 要改成下面代码---------------------------------
protected function first()
$this-&auth_rule=new \app\common\model\AuthRule();
$this-&auth_group=new \app\common\model\AuthGroup();
$this-&admins=new \app\common\model\Admins();
感觉号麻烦。。。
ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架 ,创立于2006年初,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,已经成长为国内最领先和最具影响力的WEB应用开发框架,众多的典型案例确保可以稳定用于商业以及门户级的开发。Keyboard Shortcuts?
Next menu item
Previous menu item
Previous man page
Next man page
Scroll to bottom
Scroll to top
Goto homepage
Goto search(current page)
Focus search box
Change language:
Brazilian Portuguese
Chinese (Simplified)
构造函数和析构函数
void __construct
PHP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。
如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用
parent::__construct()。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为
private 的话)。
Example #1 使用新标准的构造函数
&?phpclass&BaseClass&{&&&function&__construct()&{&&&&&&&print&"In&BaseClass&constructor\n";&&&}}class&SubClass&extends&BaseClass&{&&&function&__construct()&{&&&&&&&parent::__construct();&&&&&&&print&"In&SubClass&constructor\n";&&&}}class&OtherSubClass&extends&BaseClass&{&&&&//&inherits&BaseClass's&constructor}//&In&BaseClass&constructor$obj&=&new&BaseClass();//&In&BaseClass&constructor//&In&SubClass&constructor$obj&=&new&SubClass();//&In&BaseClass&constructor$obj&=&new&OtherSubClass();?&
为了实现向后兼容性,如果 PHP 5 在类中找不到
函数并且也没有从父类继承一个的话,它就会尝试寻找旧式的构造函数,也就是和类同名的函数。因此唯一会产生兼容性问题的情况是:类中已有一个名为
__construct() 的方法却被用于其它用途时。
与其它方法不同,当
具有不同参数的方法覆盖时,PHP 不会产生一个 E_STRICT 错误信息。
自 PHP 5.3.3 起,在命名空间中,与类名同名的方法不再作为构造函数。这一改变不影响不在命名空间中的类。
Example #2 Constructors in namespaced classes
&?phpnamespace&Foo;class&Bar&{&&&&public&function&Bar()&{&&&&&&&&//&treated&as&constructor&in&PHP&5.3.0-5.3.2&&&&&&&&//&treated&as&regular&method&as&of&PHP&5.3.3&&&&}}?&
void __destruct
PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,如
C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。
Example #3 析构函数示例
&?phpclass&MyDestructableClass&{&&&function&__construct()&{&&&&&&&print&"In&constructor\n";&&&&&&&$this-&name&=&"MyDestructableClass";&&&}&&&function&__destruct()&{&&&&&&&print&"Destroying&"&.&$this-&name&.&"\n";&&&}}$obj&=&new&MyDestructableClass();?&
和构造函数一样,父类的析构函数不会被引擎暗中调用。要执行父类的析构函数,必须在子类的析构函数体中显式调用
parent::__destruct()。此外也和构造函数一样,子类如果自己没有定义析构函数则会继承父类的。
析构函数即使在使用
终止脚本运行时也会被调用。在析构函数中调用
将会中止其余关闭操作的运行。
析构函数在脚本关闭时调用,此时所有的 HTTP
头信息已经发出。脚本关闭时的工作目录有可能和在 SAPI(如 apache)中时不同。
试图在析构函数(在脚本终止时被调用)中抛出一个异常会导致致命错误。
the easiest way to use and understand multiple constructors:
&?php
class A
{
& & function __construct()
& & {
& & & & $a = func_get_args();
& & & & $i = func_num_args();
& & & & if (method_exists($this,$f='__construct'.$i)) {
& & & & & & call_user_func_array(array($this,$f),$a);
& & & & }
& & }
& &
& & function __construct1($a1)
& & {
& & & & echo('__construct with 1 param called: '.$a1.PHP_EOL);
& & }
& &
& & function __construct2($a1,$a2)
& & {
& & & & echo('__construct with 2 params called: '.$a1.','.$a2.PHP_EOL);
& & }
& &
& & function __construct3($a1,$a2,$a3)
& & {
& & & & echo('__construct with 3 params called: '.$a1.','.$a2.','.$a3.PHP_EOL);
& & }
}
$o = new A('sheep');
$o = new A('sheep','cat');
$o = new A('sheep','cat','dog');
Be aware of potential memory leaks caused by circular references within objects.& The PHP manual states "[t]he destructor method will be called as soon as all references to a particular object are removed" and this is precisely true: if two objects reference each other (or even if one object has a field that points to itself as in $this-&foo = $this) then this reference will prevent the destructor being called even when there are no other references to the object at all.& The programmer can no longer access the objects, but they still stay in memory.Consider the following example:&?phpheader("Content-type: text/plain");class Foo {& & & & private $name;& & private $link;& & public function __construct($name) {& & & & $this-&name = $name;& & }& & public function setLink(Foo $link){& & & & $this-&link = $link;& & }& & public function __destruct() {& & & & echo 'Destroying: ', $this-&name, PHP_EOL;& & }}$foo = new Foo('Foo 1');$bar = new Foo('Foo 2');$foo-&setLink($bar);$bar-&setLink($foo);$foo = null;$bar = null;$foo = new Foo('Foo 3');$bar = new Foo('Foo 4');$foo = null;$bar = null;echo 'End of script', PHP_EOL;?&This will output:Destroying: Foo 3Destroying: Foo 4End of scriptDestroying: Foo 1Destroying: Foo 2But if we uncomment the gc_collect_cycles(); function call in the middle of the script, we get:Destroying: Foo 2Destroying: Foo 1Destroying: Foo 3Destroying: Foo 4End of scriptAs may be desired.NOTE: calling gc_collect_cycles() does have a speed overhead, so only use it if you feel you need to.
The __destruct magic method must be public. public function __destruct(){& & ;}The method will automatically be called externally to the instance.& Declaring __destruct as protected or private will result in a warning and the magic method will not be called. Note: In PHP 5.3.10 i saw strange side effects while some Destructors were declared as protected.
Correction to the previous poster about non public constructors. If I wanted to implement Singleton design pattern where I would only want one instance of the class I would want to prevent instantiation of the class from outside of the class by making the constructor private. An example follows:class Foo {& private static $& private __construct() {& & // Do stuff& }& public static getInstance() {& & if (!isset(self::$instance)) {& & & $c = __CLASS__;& & & $instance = new $c;& & }& & return self::$& }& public function sayHello() {& & echo "Hello World!!";& }}$bar = Foo::getInstance();// Prints 'Hello World' on the screen.$bar -& sayHello();
USE PARENT::CONSTRUCT() to exploit POLYMORPHISM POWERSSince we are still in the __construct and __destruct section, alot of emphasis has been on __destruct - which I know nothing about. But I would like to show the power of parent::__construct for use with PHP's OOP polymorphic behavior (you'll see what this is very quickly).In my example, I have created a fairly robust base class that does everything that all subclasses need to do. Here's the base class def.&?phpabstract class Animal{& public $type;& public $name;& public $sound;& public function __construct($aType, $aName, $aSound)& {& & $this-&type = $aType;& & $this-&name = $aName;& & $this-&sound = $aSound;& }& public static function compare($a, $b)& {& & if($a-&name & $b-&name) return -1;& & else if($a-&name == $b-&name) return 0;& & else return 1;& }& public function __toString()& {& & return "$this-&name the $this-&type goes $this-&sound";& }}?&Trying to instantiate an object of type Animal will not work...$myPet = new Animal("Parrot", "Captain Jack", "Kaaawww!"); // throws Fatal Error: cannot instantiate abstract class Animal.Declaring Animal as abstract is like killing two birds with one stone. 1. We stop it from being instantiated - which means we do not need a private __construct() or a static getInstance() method, and 2. We can use it for polymorphic behavior. In our case here, that means "__construct", "__toString" and "compare" will be called for all subclasses of Animal that have not defined their own implementations.The following subclasses use parent::__construct(), which sends all new data to Animal. Our Animal class stores this data and defines functions for polymorphism to work... and the best part is, it keeps our subclass defs super short and even sweeter.&?phpclass Dog extends Animal{& public function __construct($name){& & parent::__construct("Dog", $name, "woof!");& }}class Cat extends Animal{& public function __construct($name){& & parent::__construct("Cat", $name, "meeoow!");& }}class Bird extends Animal{& public function __construct($name){& & parent::__construct("Bird", $name, "chirp chirp!!");& }}$animals = array(& new Dog("Fido"),& new Bird("Celeste"),& new Cat("Pussy"),& new Dog("Brad"),& new Bird("Kiki"),& new Cat("Abraham"),& new Dog("Jawbone"));usort($animals, array("Animal", "compare"));foreach($animals as $animal) echo "$animal&br&\n";?&The results are "sorted by name" and "printed" by the Animal class:Abraham the Cat goes meeoow!Brad the Dog goes woof!Celeste the Bird goes chirp chirp!!Fido the Dog goes woof!Jawbone the Dog goes woof!Kiki the Bird goes chirp chirp!!Pussy the Cat goes meeoow!Using parent::__construct() in a subclass and a super smart base class, gives your child objects a headstart in life, by alleviating them from having to define or handle several error and exception routines that they have no control over.Notice how subclass definitions are really short - no variables or functions at all, and there is no private __construct() method anywhere? Notice how objects of type Dog, Cat, and Bird are all sorted by our base class Animal? All the class definitions above address several issues (keeping objects from being instantiated) and enforces the desired, consistent, and reliable behavior everytime... with the least amount of code. In addition, new extenstions can easily be created. Each subclass is now super easy to redefine or even extend... now that you can see a way to do it.
Since my last note, I've been instructed to _NEVER_ call "unset($this)", never ever ever.& Since my previous testing of behavior did not explicitly show me that it was indeed necessary, I'm inclined to trust those telling me not to do it.
As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.For example:&?phpclass Logger{& & protected $rows = array();& & public function __destruct()& & {& & & & $this-&save();& & }& & public function log($row)& & {& & & & $this-&rows[] = $row;& & }& & public function save()& & {& & & & echo '&ul&';& & & & foreach ($this-&rows as $row)& & & & {& & & & & & echo '&li&', $row, '&/li&';& & & & }& & & & echo '&/ul&';& & }}$logger = new Logger;$logger-&log('Before');$nonset-&foo();$logger-&log('After');?&Without the $nonset-&foo(); line, Before and After will both be printed, but with the line neither will be printed.One can however register the destructor or another method as a shutdown function:&?phpclass Logger{& & protected $rows = array();& & public function __construct()& & {& & & & register_shutdown_function(array($this, '__destruct'));& & }& & & & public function __destruct()& & {& & & & $this-&save();& & }& & & & public function log($row)& & {& & & & $this-&rows[] = $row;& & }& & & & public function save()& & {& & & & echo '&ul&';& & & & foreach ($this-&rows as $row)& & & & {& & & & & & echo '&li&', $row, '&/li&';& & & & }& & & & echo '&/ul&';& & }}$logger = new Logger;$logger-&log('Before');$nonset-&foo();$logger-&log('After');?&Now Before will be printed, but not After, so you can see that a shutdown occurred after Before.
With the destructor if you're going to write to a file make sure you have the full file path and not just the filename, it seems PHP switches the working directory to the apache root directory when exiting the script.
The fact that class names are case-insensitive in PHP5 also applies to constructors. Make sure you don't have any functions named like the class *at all*.This has bitten me a few times.&?phpclass Example extends Base{& function example()& {& & echo "This gets called";& }}class Base{& function __construct()& {& & echo "Not this";& }}?&
By inheriting from this class, you can do constructor overloading in terms of type hinting.&?php&& abstract class OverloadedConstructors {& & & public final function __construct() {& & & && $self = new ReflectionClass($this);& & & && $constructors = array_filter($self-&getMethods(ReflectionMethod::IS_PUBLIC), function(ReflectionMethod $m) {& & & & & & return substr($m-&name, 0, 11) === '__construct';& & & && });& & & && if(sizeof($constructors) === 0)& & & & & & trigger_error('The class ' . get_called_class() . ' does not provide a valid constructor.', E_USER_ERROR);& & & && $number = func_num_args();& & & && $arguments = func_get_args();& & & && foreach($constructors as $constructor) {& & & & & & if(($number &= $constructor-&getNumberOfRequiredParameters()) &&& & & & & & && ($number &= $constructor-&getNumberOfParameters())) {& & & & & & && $parameters = $constructor-&getParameters();& & & & & & && reset($parameters);& & & & & & && foreach($arguments as $arg) {& & & & & & & & & $parameter = current($parameters);& & & & & & & & & if($parameter-&isArray()) {& & & & & & & & & && if(!is_array($arg))& & & & & & & & & & & & continue 2;& & & & & & & & & }elseif(($expectedClass = $parameter-&getClass()) !== null) {& & & & & & & & & && if(!(is_object($arg) && $expectedClass-&isInstance($arg)))& & & & & & & & & & & & continue 2;& & & & & & & & & }& & & & & & & & & next($parameters);& & & & & & && }& & & & & & && $constructor-&invokeArgs($this, $arguments);& & & & & & &&& & & & & & }& & & && }& & & && trigger_error('The required constructor for the class ' . get_called_class() . ' did not exist.', E_USER_ERROR);& & & }&& }?&Simply define a class like this:&?php&& class Test extends OverloadedConstructors {& & & public function __construct1(array $arg) {& & & && die('First construct');& & & }& & & public function __construct2(stdClass $test) {& & & && die('Second construct');& & & }& & & public function __construct3($optional = null) {& & & && die('Third construct');& & & }&& }?&You can define as much constructors as you wish and limit them by php's type hinting. Note that the constructor signatures should be non-ambiguous.
multiple constructors with type signetures (almost overloading):
&?php
public function __construct() {
& & & & $args = func_get_args();
& & & & $argsStr = '';
& & & & foreach ($args as $arg) {
& & & & & & $argsStr .= '_' . gettype($arg);
& & & & }
& & & & if (method_exists($this, $constructor = '__construct' . $argsStr))
& & & & & & call_user_func_array(array($this, $constructor), $args);
& & & & else
& & & & & & throw new Exception('NO CONSTRUCTOR: ' . get_class() . $constructor, NULL, NULL);
& & }
public function __construct_integer($a) {}
public function __construct_string($a) {}
public function __construct_integer_string($a, $b) {}
public function __construct_string_integer($a, $b) {}
?&
[quote]Note:Attempting to throw an exception from a destructor (called in the time of script termination) causes a fatal error.[/quote]Not true.Usually you wont be able to catch an Exception thrown out of a ::__destruct().BUT following case shows that it IS possible to catch a thrown Exception from the ::__destruct()&?phpclass Something{& & public function __construct()& & {& & & & echo __METHOD__ . PHP_EOL;& & }& & public function __destruct()& & {& & & & echo __METHOD__ . PHP_EOL;& & & & throw new Exception("Exception thrown out of ::__destruct()", 1);& & }}try{& & $Something = new Something();& & $Something = null; }catch(Exception $e){& & echo 'Exception: ' . $e-&getMessage() . PHP_EOL;}echo 'End of script -- no Fatal Error.';?&IMO this is not a bug. It is ok to be able to throw and catch Exception.
It's always the easy things that get you -Being new to OOP, it took me quite a while to figure out that there are TWO underscores in front of the word __construct.It is __constructNot _constructExtremely obvious once you figure it out, but it can be sooo frustrating until you do.I spent quite a bit of needless time debugging working code.I even thought about it a few times, thinking it looked a little long in the examples, but at the time that just seemed silly(always thinking "oh somebody would have made that clear if it weren't just a regular underscore...")All the manuals I looked at, all the tuturials I read, all the examples I browsed through& - not once did anybody mention this!& (please don't tell me it's explained somewhere on this page and I just missed it,& you'll only add to my pain.)I hope this helps somebody else!
putting in more layman's termclass dad{& & & & function __construct() {& & & & echo get_class($this) . ' is fair and tall &br&';& & }}//inherit and overidding parent constructorclass son extends dad{& & & & function __construct(){& & & & parent::__construct();& & & & echo get_class($this) . ' is handsome &br&';& & }}//overidding parent constructorclass daughter extends dad{& & function __construct(){& & & & echo get_class($this) . ' is tan like her mother &br&';& & & & echo get_class($this) . ' is pretty and has nothing to do with dad &br&';& & }}echo 'im dad: &br&';$dad = new dad();echo '&br&';echo 'born a son: &br&';$son = new son();echo '&br&';echo 'born a daughter: &br&';$daughter = new daughter();/*outputim dad:dad is fair and tallborn a son:son is fair and tall (notice that when parent:: is call inside son, son will be the class inside dad's contructor)son is handsomeborn a daughter:daughter is tan like her motherdaughter is pretty and has nothing to do with dad */
This is just to clarify that the Singleton pattern is a bit more complex than just making the constructor private. It also involves caching an instance of the object and always returning the cached value. So, in the previous example, the getNewInstance() function would undermine the intent of the Singleton pattern. Instead you would just need a getInstance() function, like so.&?phpclass A {& private static oInst = null;& private function __construct( ) {}& public static function getInstance( ) {& & if (is_null(self::$oInst)) {& & & self::$oInst = new A( );& & }& & return self::$oInst;& }}?&
Another way to emulate multiple constructors:&?phpclass MyClass {&& function __construct($id="", $args=null) {& & && parent::__construct();& & && echo "main constructor\n";& & & $id = (string) $id;& & & if ($id == "") {& & & & && $id = "default";& & & }& & & $id = "__cons_" .& strtolower($id);& & & $rc = new ReflectionClass("MyClass");& & & if (!$rc-&hasMethod($id) {& & & && echo "constructor $id not defined\n";& & & }& & & else { & & & & $this-&$id($args);& & & }& & && $rc = null;&& } function __cons_default($args=null) {& & && echo "Default constructor\n";&& }&& function __cons_min($args=null) {& && if (! is_array($args) || count($args) != 2) {& & && echo "Error: Not enough parameters (Constructor min(int $a, int $b)) !!!\n";& && }& && else {& & & && $a = (int) $args[0];& & & && $b = (int) $args[1];& & & && $c = min($a,$b);& & & && echo "Constructor min(): Result = $c\n";& && }&& }&& function __cons_fullname($args=null) {& && if (! is_array($args) || count($args) & 2) {& & && echo "Error: Not enough parameters (Constructor fullname(string $firstname, string $lastname)) !!!\n";& && }& && else {& & & && $a = (string) $args["firstname"];& & & && $b = (string) $args["lastname"];& & & && $c = $a . " " . $b;& & & && echo "Constructor fullname(): Result = $c\n";& && }&& }} $obj1 = new TestClass();$obj2 = new TestClass("default");$obj3 = new TestClass("min", array(99.7, 99.83));$obj4 = new TestClass("fullname", array("firstname" =& "John", "lastname" =& "Doe"));$obj5 = new TestClass("min", array());$obj6 = new TestClass("fullname");?&
Please be aware of when using __destruct() in which you are unsetting variables...Consider the following code:&?phpclass my_class {& public $error_reporting = false;& function __construct($error_reporting = false) {& & $this-&error_reporting = $error_reporting;& }& function __destruct() {& & if($this-&error_reporting === true) $this-&show_report();& & unset($this-&error_reporting);& }?&The above will result in an error:Notice: Undefined property: my_class::$error_reporting in my_class.php on line 10It appears as though the variable will be unset BEFORE it actually can execute the if statement.& Removing the unset will fix this.& It's not needed anyways as PHP will release everything anyways, but just in case you run across this,)
at the end of a script all remaining objects aren't in fact destructed. it is only their __destruct() method, which will be called. the objects still exist after that.so, if your database connection object has no __destruct() or at least it doesn't disconnects the database, it will still work.in general, there is no need to disconnect the database (especially for persistent connections).
i have written a quick example about the order of destructors and shutdown functions in php 5.2.1:&?phpclass destruction {& & var $name;& & function destruction($name) {& & & & $this-&name = $name;& & & & register_shutdown_function(array(&$this, "shutdown"));& & }& & function shutdown() {& & & & echo 'shutdown: '.$this-&name."\n";& & }& & function __destruct() {& & & & echo 'destruct: '.$this-&name."\n";& & }}$a = new destruction('a: global 1');function test() {& & $b = new destruction('b: func 1');& & $c = new destruction('c: func 2');}test();$d = new destruction('d: global 2');?&this will output:shutdown: a: global 1shutdown: b: func 1shutdown: c: func 2shutdown: d: global 2destruct: b: func 1destruct: c: func 2destruct: d: global 2destruct: a: global 1conclusions:destructors are always called on script end.destructors are called in order of their "context": first functions, then global objectsobjects in function context are deleted in order as they are set (older objects first).objects in global context are deleted in reverse order (older objects last)shutdown functions are called before the destructors.shutdown functions are called in there "register" order. ;)regards, J
Peter has suggested using static methods to compensate for unavailability of multiple constructors in PHP.& This works fine for most purposes, but if you have a class hierarchy and want to delegate parts of initialization to the parent class, you can no longer use this scheme.& It is because unlike constructors, in a static method you need to do the instantiation yourself.& So if you call the parent static method, you will get an object of parent type which you can't continue to initialize with derived class fields.Imagine you have an Employee class and a derived HourlyEmployee class and you want to be able to construct these objects out of some XML input too.&?phpclass Employee {&& public function __construct($inName) {& & && $this-&name = $inName;&& }&& public static function constructFromDom($inDom)&& {& & && $name = $inDom-&name;& & && return new Employee($name);&& }&& private $name;}class HourlyEmployee extends Employee {&& public function __construct($inName, $inHourlyRate) {& & && parent::__construct($inName);& & && $this-&hourlyRate = $inHourlyRate;&& }&& public static function constructFromDom($inDom)&& {& & && $name = $inDom-&name;& $hourlyRate = $inDom-&hourlyrate;& & && return new EmployeeHourly($name, $hourlyRate);&& }&& private $hourlyRate;}?&The only solution is to merge the two constructors in one by adding an optional $inDom parameter to every constructor.
&?phpclass Mobile {& & public $deviceName,$deviceVersion,$deviceColor;& & & & public function __construct ($name,$version,$color) {& & & & $this-&deviceName = $name;& & & & $this-&deviceVersion = $version;& & & & $this-&deviceColor = $color;& & & & echo "The ".__CLASS__." class is stratup.&br /&&br /&";& & }& & & & public function printOut () {& & & & echo 'I have a '.$this-&deviceName& & & & & & .' version '.$this-&deviceVersion& & & & & & .' my device color is : '.$this-&deviceColor;& & }& & & & public function __destruct () {& & & & $this-&deviceName = 'Removed';& & & & echo '&br /&&br /&Dumpping Mobile::deviceName to make sure its removed, Olay :';& & & & var_dump($this-&deviceName);& & & & echo "&br /&The ".__CLASS__." class is shutdown.";& & }}$mob = new Mobile('iPhone','5','Black');$mob-&printOut();?&The Mobile class is stratup.I have a iPhone version 5 my device color is : BlackDumpping Mobile::deviceName to make sure its removed, Olay :string 'Removed' (length=7)The Mobile class is shutdown.
You can also capitalize on singleton for the connection as well.
Just add the following to your class:
&?php
class db {
& private static $instance;
& public static function singleton() {
& & if(!isset(self::$instance)) {
& & & $c = __CLASS__;
& & & self::$instance = new $c();
& & }
& & return self::$instance;
& }
& }
?&
for multiple constructor like, you can use the constructor this wayclass Foo{& & public function __construct(...$args)& & {& & & & if (count($args) == 1) {& & & & & & echo 'One parameter';& & & & } else if (count($args == 2)) {& & & & & & echo 'Two parameter';& & & & } else {& & & & & & echo 'More than one parameter';& & & & }& & }}new Foo('hello', 'world');
This two documents shows how OOP can work with using a constructor. [Document user.php]&?phpclass user{& private $name;& & & & private $forename;& & private $birthday;& & private $username;& & public function __construct($n,$fn,$bd)& {& & if(strlen($n)&=3 && strlen($fn)&=2)& & {& & & & $this-&name=$n;& & & & $this-&forename=$fn;& & }& & $this-&birthday=$bd;& }& public function getName()& {& & if($this-&name!="")& & {& & & return $this-&name;& & }& & else& & {& & & return "&strong style='color:red'& Name required.&/strong&";& & }& }& public function getForename()& {& & if($this-&forename!="")& & {& & & return $this-&forename;& & }& & else& & {& & & return "&strong style='color:red'&Forename required.&/strong&";& & }& }& public function getBirthday()& {& & if($this-&birthday!="")& & {& & & return $this-&birthday;& & }& & else& & {& & & return "&strong style='color:red'&Birthday required.&/strong&";& & }& }& public function getUsername()& {& & if($this-&username!="")& & {& & & return $this-&username;& & }& & elseif($this-&name!=""&&$this-&forename!="")& & {& & & $this-&createUN();& & & return $this-&username;& & }& & else& & {& & & return"&strong style='color:red'&Username can not created. &/strong&";& & }& }& & public function createUN()& {& & $username="";& & for($i=0;$i&=3;$i++)& & {& & & $username[$i]= $this-&name[$i];& & }& & for($i=0;$i&=1;$i++)& & {& & & $username[$i+2]= $this-&forename[$i];& & }& & $username=implode("",$username); return $username;& }}?&//-------------------------------------------------------------------------------[Document user_test.php]&?phpinclude("user.php");$user1= new user("Musterman","Max","31.01.1998");& echo $user1-&getForename();echo $user1-&getName();echo $user1-&getBirthday();echo $user1-&createUN();?&
If your code has a redundant constructor for PHP 4 compatibility, an E_STRICT error may be raised in PHP 5.x:Strict Standards:& Redefining already defined constructor for class...What is a redundant constructor for PHP 4 compatibility? It looks like&?phpClass Foo {& function Foo() {& & return $this-&__construct();& }& function __construct() {& & }?&If you don't need PHP 4, just delete the Foo function. Or you reverse the order of Foo and __construct, the error goes away, so that's probably OK for a single class. Also there was a suggestion to do this in Foo:&?php& function Foo() {& & if (version_compare(PHP_VERSION,"5.0.0","&")) {& & & return $this-&__construct();& & }& }?&
Php 5.3.3 had a very strange bug, related to __destruct, but this bug was fixed in 5.3.6. This bug happened to me and it took me forever to figure it out, so I wanted to share it.In short, don't unset properties in __destruct():&?phpclass Foobar {& & public $baz;& & function __destruct() {& & & & $this-&baz = null;& & & & unset($this-&baz);& & & & & & & & $this-&baz-&__destruct();& & }}?&If you made this mistake, this might happen in php&5.3.6:&?phpfunction fail($foobar) {& & throw new Exception("Exception A!");}$foobar = new Foobar();$foobar-&baz = new Foobar();try {& & fail($foobar); } catch( Exception $e ) {& & print $e-&getMessage(); }$foobar = null; try {& & print 'Exception B:';throw new Exception("Exception B!");} catch( Exception $e ) {& & print $e-&getMessage(); }print 'End'; ?&
Another way to overcome PHP's lack of multi constructors support is to check for the constructor's parameters' type and variate the operation accordingly. This works well when the number of parameters stays the same in all your constructors' needs.Example:&?phpclass Articles {& & private $_articles_array;& & public function __construct($input) {& & & & if (is_array($input)) {& & & & & & }& & & & else if ($input instanceof SimpleXMLElement) {& & & & & & }& & & & else {& & & & & & throw new Exception('Wrong input type');& & & & }& & }}?&
For those who still ***have*** to deal with php4 (like myself, which sucks), contact at tcknetwork dot com noted below that you can have both __constructor and function [classname] in the script, as __constructor has priority.However, to further improve compatability, do a version check in function [classname], as I do in my classes as follows:&?php&& class Foo{& & & function __construct($arg){& & & && echo $arg;& & & }& & & function Foo($arg){& & & && if(version_compare(PHP_VERSION,"5.0.0","&")){& & & & & & $this-&__construct($arg);& & & & & & register_shutdown_function(array($this,"__destruct"));& & & & & & & & && }& & & }& & & function __destruct(){& & & && echo "Ack! I'm being destroyed!";& & & }&& }?& This makes it much easier to use your script with fewer compatibility issues.
Ensuring that instance of some class will be available in destructor of some other class is easy: just keep a reference to that instance in this other class.
When a script is in the process of die()ing, you can't count on the order in which __destruct() will be called.For a script I have been working on, I wanted to do transparent low-level encryption of any outgoing data.& To accomplish this, I used a global singleton class configured like this:class EncryptedComms{& & private $C;& & private $objs = array();& & private static $_& & & & public static function destroyAfter(&$obj)& & {& & & & self::getInstance()-&objs[] =& $& & & & /*& & & & & & Hopefully by forcing a reference to another object to exist & & & & & & inside this class, the referenced object will need to be destroyed& & & & & & before garbage collection can occur on this object.& This will force & & & & & & this object's destruct method to be fired AFTER the destructors of& & & & & & all the objects referenced here.& & & & */& & }& & public function __construct($key)& & {& & & & & & $this-&C = new SimpleCrypt($key);& & & & & & ob_start(array($this,'getBuffer'));& & }& & public static function &getInstance($key=NULL)& & {& & & & if(!self::$_me && $key)& & & & & & self::$_me = new EncryptedComms($key);& & & & else& & & & & & return self::$_& & }& & & & public function __destruct()& & {& & & & ob_end_flush();& & }& & & & public function getBuffer($str)& & {& & & & return $this-&C-&encrypt($str);& & }}In this example, I tried to register other objects to always be destroyed just before this object.& Like this:class A{public function __construct(){& && EncryptedComms::destroyAfter($this);}}One would think that the references to the objects contained in the singleton would be destroyed first, but this is not the case.& In fact, this won't work even if you reverse the paradigm and store a reference to EncryptedComms in every object you'd like to be destroyed before it.In short, when a script die()s, there doesn't seem to be any way to predict the order in which the destructors will fire.
The manual says:"Like constructors, parent destructors will not be called implicitly by the engine."This is true ONLY when a __destruct() function has been defined by the child class.If no __destruct() function exists in the child class, the parent's one will be implicitly executed.So be carefull if you have some ancestor executing a particular task in its __destruct() function, an you plan its childs to execute it or not, wether you include "parent::__destruct()" or not.If you want the child not to execute its parent __destruct() function, you must ensure that it has its own __destruct() function, even if empty. Then the parent's one will not be executed.This can be verified with the following code:&?phpclass AncestorClass {& & function __destruct() {& & & & echo '&br /&AncestorClass: destructing '.get_class($this);& & }}class ParentDestructClass extends AncestorClass {& & function __destruct() {& & & & echo 'ParentDestructClass: destructing itself';& & & & parent::__destruct();& & }}class EmptyDestructClass extends AncestorClass {& & function __destruct() {& & & & echo 'EmptyDestructClass: destructing itself';& & }}class NoDestructClass extends AncestorClass {}echo '&hr&';$p=new ParentDestructClass();unset($p);echo '&hr&';$e=new EmptyDestructClass();unset($e);echo '&hr&';$n=new NoDestructClass();unset($n);echo '&hr&';?&which displays:---ParentDestructClass: destructing itselfAncestorClass: destructing ParentDestructClass---EmptyDestructClass: destructing itself---AncestorClass: destructing NoDestructClass---
This is a simple thing to bear in mind but it's also easy to forget it.& When chaining object constructors and destructors, always remember to call the superclass __construct() method in the subclass __construct() so that all superclass members are properly initialized before you start initializing the ones belonging to your subclass.& Also, you will usually want to do your own cleanup first in your subclass __destruct() method so you will probably want to call the superclass __destruct() as the last thing in your subclass so that you can use resources defined in the superclass during the cleanup phase. For example, if your superclass includes a database connection and your subclass __destruct method commits things to the database then if you call the superclass destruct before doing so then the database connection will no longer be valid and you will be unable to commit your changes.
be careful while trying to access files with __destruct() because the base directory (getcwd()) will be the root of your server and not the path of your script, so add before all your path called in __destruct() :EITHER&& dirname($_SERVER["SCRIPT_FILENAME"])."my/path/"OR& & & dirname(__FILE__)."my/path/"& & & && (be careful with includes, it will give the path of the file processed and not the main file)
It's usefull to note that parent::__construct() is executed like a standalone function called into the new one, and not like a first part of the code. So "return" or "die()" don't have effect on following code. If you want to avoid the execution of the child constructor you have to pass some condition from the parent. Example:
&?php
class X {
& function X(){
& & if($_POST['break']=='yes'){}
& & }
& }
class Y extends X{
& function Y(){
& & parent::__construct();
& & print("Y_constructor_finished");
& & }
& }
$_POST['break']=='yes';
$new_Y=new Y();& Solution:
class X {
& function X(){
& & if($_POST['break']=='yes'){$this-&break='yes';}
& & }
& }
class Y extends X{
& function Y(){
& & parent::__construct();
& & if($this-&break=='yes'){}
& & print("Y_constructor_finished");
& & }
& }
$_POST['break']='yes';
$new_Y=new Y();& ?&
While experimenting with destructs and unsets in relation to memory usage, I found what seems to be one useful way to predict when __destruct() gets called... call it manually yourself.I had previously assumed that explicitly calling unset($foo) would cause $foo-&__destruct() to run implicitly, but that was not the behavior I saw (php 5.2.5).& The destructors weren't running until the script ended, even though I was calling unset($foo) in the middle of my script.& So, having $foo-&__destruct() unset all of $foo's component objects was not helping my memory usage since my explicit unset($foo) was _not_ triggering $foo-&__destruct()'s cleanup steps.Interestingly, what _did_ appear to happen is that calling unset($bar) from inside a destructor like $foo-&__destruct() _DID_ cause $bar-&__destruct() to be implicitly executed.& Perhaps this is because $bar has a "parent" reference of $foo whereas $foo does not, and the object destruction behaves differently... I don't know.Lastly, even after explicitly calling $foo-&__destruct() (even when it had "unset($this);" inside it), the reference to the $foo object remained visible.& I had to still explicitly call unset($foo) to get rid of it.So, my advice based on the behavior I saw in my experiments:- always unset($bar) your class's component objects from inside that class's __destruct()& no explicit component destructor calls seem to be required other than those unsets, though.- always explicitly call $foo-&__destruct() in your code that _uses_ your class- always explicitly follow $foo-&__destruct() with unset($foo).This seems to be the best cleanup approach to take.& Just for my own sanity, I also will always keep an unset($this) at the end of each __destruct() method.
Constructor SimplicityIf your class DOES CONTAIN instance members (variables) that need to be set, then your class needs to be initialized... and you should use __construct() to do that.&?phpclass MyClassA {& public $data1, $data2;& public function __construct($mcd1, $mcd2) {& & $this-&data1 = $mcd1;& $this-&data2 = $mcd2;& }}$obj1 = new MyClassA("Hello", "World!");& $d1 = $obj1-&data1;$d2 = $obj1-&data2;?&If your class DOES NOT CONTAIN instance members or you DO NOT want to instantiate it, then there is no reason to initialize it or use __construct().&?phpclass MyClassB {& const DATA1 = "Hello";& public static $data2 = "World!";}$obj1 = new MyClassB();& $d1 = $obj1::DATA1;& & & $d2 = $obj1::data2;& & & $d1 = MyClassB::DATA1;&& $d2 = MyClassB::$data2;& ?&The fact that $obj1 is useless and cannot be used as a reference, is further evidence that MyClassB objects should not be instantiated. NOTICE that MyClassB does not use private members or functions to make it behave that way. Rather, it is the collective nature of all the class members + what ISN'T there.
In regards to a Class Constructor visibility ...I too was having the same problem with Class Constructor visibility, in which I had one Class that was extended by several other Classes. The problem that I encountered was in one of the Child Classes, I wanted a weaker visibility. Consider the following example:&?phpclass A {& & & & public function __construct( ) {& & & & & & }& & & & public function functionA( ) {& & & & & & }}class B extends A {& & & & public function __construct( ) {& & & & & & }& & & & public function functionB( ) {& & & & & & }}class C extends A {& & & & private function __construct( ) {& & & & & & }& & & & public function functionC( ) {& & & & & & }}?&Nothing new in the above example that we have not seen before. My solution to solve this problem?Create an Abstract Class with all the functionality of Class A.& Make its Class Constructor have a visibility of Protected, then extend each of the three Classes above from that Abstract Class. In a way, the Abstract Class acts as a dummy Class to get rid of the visibility problem:&?phpabstract class AAbstract {& & & & protected function __construct( ) {& & & & & & }& & & & public function functionA( ) {& & & & & & }}class A extends AAbstract {& & & & public function __construct( ) {& & & & & & & & parent::__construct( );& & }& & & & }class B extends AAbstract& {& & & & public function __construct( ) {& & & & & & & & parent::__construct( );& & }& & & & public function functionB( ) {& & & & & & }}class C extends AAbstract {& & & & protected function __construct( ) {& & & & & & }& & & & public function functionC( ) {& & & & & & }}?&As you can see the problem is more or less fixed. Class AAbstract acts a dummy class, containing all the original functionality of Class A. But because it has a protected Constructor, in order to make its functionality available, Class A is redeclared as Child Class with the only difference of it having a public Constructor that automatically calls the Parent Constructor.Notice that Class B does not extend from Class A but also from Class AAbstract! If I wanted to change Class B's Constructor to protected, I can easily do it! Notice that an extra Method was added to Class B ... this is because Class B has extra functionality specific to itself. Same applies to Class C.Why don't Class B and Class C extend from Class A? Because Class A has a public Constructor, which pretty much defies the point of this solution.This solution is not perfect however and has some flaws.Good Luck,
There were many notes about the inability of defining multiple constructors for the class.My solution is to define separate static methods for each type of constructor.&?phpclass Vector {& & private $x;& & private $y;& & public function __construct() {& & & & $this-&x = 0;& & & & $this-&y = 0;& & }& & public static function createXY($x, $y) {& & & & $v = new Vector();& & & & $v-&x = $x;& & & & $v-&y = $y;& & & & return $v;& & }}?&
It looks like `echo()`ed output from the __destructor() function is displayed onto screen _before_ other output that the class may have have already sent before.This can be misleading if you have debug info printed in the destructor but not a problem if you know it.
I just thought I'd share some valuable information that might help novice programmers/scripters in __constructor() functions.I've been using PHP for quite a long time, as well as programming and scripting in general.& Even with my quite seasoned skillset, I still make obvious, painstaking mistakes.& That said, I'd like to point out one major (albeit obvious) common mistake that programmers and scripters (such as myself) make.When defining the constructor for an object and using it to populate variables for use throughout the lifetime of the application, do note that if you set a static variable AFTER a dynamic one, the static variable's (intended) contents are not readible inside the assigning functions of a dynamic variable.& (That sounded rather cryptic, so an example is in order...)&?phpclass ExampleClass{& & public $myStaticVar;& & & & public $myDynamicVar; & & & & public function __construct($myStaticVarValue)& & {& & & & $this-&myDynamicVar = $this-&setSomeValue();& & & & & & & & $this-&myStaticVar = $myStaticVarValue;& & }& & & & public function setSomeValue()& & {& & & & return $this-&myStaticVar;& & }}$object = new ExampleClass('Static Variable Value');print $object-&myDynamicVar;?&The above example won't print anything because you're setting the $myDynamicVar to equal the $myStaticVar, but the $myStaticVar hasn't been (technically) assigned to, yet.So, if you wish to reference that variable inside the assignment function of a dynamic variable, you have to declare it first and foremost.& Otherwise, its value will not be accessible yet.The correct way...&?phpclass ExampleClass{& & public $myStaticVar;& & & & public $myDynamicVar; & & & & public function __construct($myStaticVarValue)& & {& & & & $this-&myStaticVar = $myStaticVarValue;& & & & & & & & $this-&myDynamicVar = $this-&setSomeValue();& & }& & & & public function setSomeValue()& & {& & & & return $this-&myStaticVar;& & }}$object = new ExampleClass('Static Variable Value');print $object-&myDynamicVar;?&
__construct and __destruct must be declared public in any class that you intend to instantiate with new.&& However, in an abstract (or never-instantiated base) class you can declare them private or protected, and subclasses can still refer to them via parent::__construct (!) (tested in PHP 5.1.2).
I ran into an interesting (and subtle) code error while porting some code to PHP 5.2.5 from PHP 4.4.8 that I think illustrates a noteworthy semantic.I have a hierarchy of classes with both styles of constructors but where one in the middle was missing the __construct() function (it just had the old-style one that called the (nonexistent) __construct()).& It worked fine in PHP4 but caused an endless loop (and stack overflow) in PHP5.& I believe what happened is that in PHP4 the old-style constructor was not called, but in PHP5 it was (due to the "emulation" of PHP4), and since _construct() wasn't defined for that class, the call to $this-&__construct() caused a looping call to the original (lowest child) constructor.
Looking through the notes I noticed a few people expressing concern that PHP5 does not support multiple constructors...Here is an example of a method that I use which seems to work fine:class Example{& && function __construct()& && {& & & & && echo "do some basic stuff here";& && }& && function Example($arg)& && {& & & & && echo $& && }}You then can call with or without arguments without having notices and/or warnings thrown at you... Of course this is limited but if you don't need something complex this can help to get the job done in some situations.& I believe you could also add arguments to the __construct() function and as long as it is different than Example() 's args you would be fine. Although I have yet to test this.
Should be noted that according to the NEWS (in PHP 5.3) file, in PHP 5.3, handling an exception in the __destructor should not output a FATAL error ...
Hello, I've been messing with php for about a week but am learning a lot.& It occurred to me that it might be necessary in some cases to write a class that takes a variable number of arguments.& After some experimentation, this example was formed:class variableArgs{public $a = array();protected $numOfApublic function __construct(){& $numOfArgs=func_num_args();& if(func_num_args()==0)& {& & $numOfArgs=1;& & $a[0]='No arguments passed';& & $this-&Arg[0]=$a[0];& }& else& for($i=0; $i&func_num_args(); $i++)& {& & $a[$i]=func_get_arg($i);& & $this-&Arg[$i]=$a[$i];& }}public function showArgs(){& echo 'showArgs() called &br /&';& for ($i=0; $i&$numOfA $i++)& {& & echo '$i: ' . $i . '&br /&';& & echo $this-&Arg[$i];& & echo '&br /&';& }}public function __destruct(){}}$test1 = new variableA$test2 = new variableArgs("arg1");$test3 = new variableArgs("arg1", "arg2");$test4 = new variableArgs("arg1", "arg2", "arg3");$test1-&showArgs();$test2-&showArgs();$test3-&showArgs();$test4-&showArgs();This outputs the following:showArgs() called $i: 0No arguments passedshowArgs() called $i: 0arg1showArgs() called $i: 0arg1$i: 1arg2showArgs() called $i: 0arg1$i: 1arg2$i: 2arg3I have no idea how efficient this is, but it works at any rate.& Hopefully this helps someone.
The manual page says that throwing an exception from a destructor & I've found that this only happens when the exception is _uncaught_ within the context of that destructor.& If you catch it within that same destructor it seems to be fine.This is equally true of other contexts, such as:- shutdown functions set with register_shutdown_function- destructors- custom session close functions- custom error handlers- perhaps other similar contextsAn exception normally 'bubbles up' to higher and higher contexts until it is caught, but because a destructor or shutdown function is called not within execution flow but in response to a special PHP event, the exception is unable to be traced back any further than the destructor or shutdown function in which it is called.
Note that if a class contains another class, the contained class's destructor will be triggered after the destructor of the containing class.&?phpclass contained {
protected $parent; public function __construct(&$p) {& }
public function __destruct() {& print 'contained ';& } } class containing { protected $contained; public function __construct() {& $this-&contained=new contained($this);& }
public function __destruct() {& print 'containing ';& } }
new containing();?&Will outputcontaining containedAfter uncommenting the // comment, the output will change tocontained containing Adding a reference from the contained class to the containing one (the # comment) will not change that, but beware, because it can cause random errors in other destructors in the parts of the script which seem unrelated! (PHP Version 5.1.2)
I recently found, while implementing a database backed session class, that PHP has an apparently less than desirably structured destruction order. Basically, my session class which would have saved when destructed, was being destructed after one of the classes it depends on. Apparently we cannot, therefore depend on PHP to use reverse initialisation order.My solution was to use register_shutdown_function, which is called before any objects are killed on script end.Quick example (if you're going to use it, I recommend tidying up the code somewhat) :&?phpclass Session& function __construct()& {& & register_shutdown_function(array($this,"save"));& }& function save()& {& & }& function __destruct()& {& & }?&
If you're using E_STRICT error reporting, PHP will tell you if you define both __construct() and an old-style constructor (a function with the same name as the class) together in a class. Note that this occurs even if the old constructor function is abstract or final (for instance, if you were intending to only use it in a sub-class). Be wary of this if you're trying to implement the 'command' design pattern.The solution? Either turn E_STRICT off (and possibly forgo some other important notices), rename your function (and possibly make things a little more complicated), or look at using an interface.
I just find out that you can instantiate an object from another object:&&& $dt = new Datetime();=& DateTime {#174& && +"date": " 11:00:08.000000",& && +"timezone_type": 3,& && +"timezone": "Asia/Shanghai",&& }&&& new $dt();=& DateTime {#167& && +"date": " 11:00:18.000000",& && +"timezone_type": 3,& && +"timezone": "Asia/Shanghai",&& }&&&
If a new reference of the object is created during __destruct, the memory for the object will not be freed, and the __destruct will not be called for a second time.&?phpclass Foo{& & public $i = "I=\n";& & & & public function showI(){& & & & echo($this-&i);& & }& & & & public function __destruct(){& & & & echo("in __destruct\n");& & & & if($GLOBALS['flag'])& & & & & & $GLOBALS['test'][0] = $this;& & }}$flag = true;$test = [new Foo()];echo("deleting Foo\n");unset($test[0]);echo("deleted Foo\n");$test[0]-&showI();$flag = false;echo("re-deleting Foo\n");unset($test[0]);echo("deleted Foo\n");?&In the above example, the output is:deleting Fooin __destructdeleted FooI=re-deleting Foodeleted Fooso the __destruct was called only once and the memory was not freed.
What you could do is write the constructor without any declared arguments, then iterate through the arguments given and check their types/values to determine what other function to use as the constructor.
As far as I can tell, Connection: close isn't sent until after __destruct is called in shutdown sequence.I was hoping to get the HTTP connection closed and done, and do some slow non-output processing after that, but no luck.}

我要回帖

更多关于 php 默认构造函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信