_Construct() VS Sameasclassname() for Constructor in PHP

__construct() vs SameAsClassName() for constructor in PHP

I agree with gizmo, the advantage is so you don't have to rename it if you rename your class. DRY.

Similarly, if you have a child class you can call

parent::__construct()

to call the parent constructor. If further down the track you change the class the child class inherits from, you don't have to change the construct call to the parent.

It seems like a small thing, but missing changing the constructor call name to your parents classes could create subtle (and not so subtle) bugs.

For example, if you inserted a class into your heirachy, but forgot to change the constructor calls, you could started calling constructors of grandparents instead of parents. This could often cause undesirable results which might be difficult to notice.

Also note that

As of PHP 5.3.3, methods with the same name as the last element of a namespaced class name will no longer be treated as constructor. This change doesn't affect non-namespaced classes.

Source: http://php.net/manual/en/language.oop5.decon.php

use Classname() or __construct() as constructor in CodeIgniter?

Classname() is the old way (i.e. PHP 4 way).

__construct() is the new (i.e. PHP 5) way.

You should use the second one, if your application is written with PHP 5 -- and you should write your applications with PHP 5 in mind !


See the Constructors and Destructors section in the manual, which states (quoting) :

For backwards compatibility, if PHP 5
cannot find a __construct() function
for a given class, it will search for
the old-style constructor function, by
the name of the class.

When do/should I use __construct(), __get(), __set(), and __call() in PHP?

This page will probably be useful. (Note that what you say is incorrect - __set() takes as a parameter both the name of the variable and the value. __get() just takes the name of the variable).

__get() and __set() are useful in library functions where you want to provide generic access to variables. For example in an ActiveRecord class, you might want people to be able to access database fields as object properties. For example, in Kohana PHP framework you might use:

$user = ORM::factory('user', 1);
$email = $user->email_address;

This is accomplished by using __get() and __set().

Something similar can be accomplished when using __call(), i.e. you can detect when someone is calling getProperty() and setProperty() and handle accordingly.

What's difference between __construct and function with same name as class has?

The method named is the PHP4 way of doing a constructor.

For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, it will search for the old-style constructor function, by the name of the class. Effectively, it means that the only case that would have compatibility issues is if the class had a method named __construct() which was used for different semantics.

As of PHP 5.3.3, methods with the same name as the last element of a namespaced class name will no longer be treated as constructor. This change doesn't affect non-namespaced classes.

http://www.php.net/manual/en/language.oop5.decon.php

Why is the last method with same name of the namespaced class not considered a constructor in PHP 5.3.3?

Regarding why this rule applies for namespaced classes vs. non-namespaced, PHP 5.3 introduced namespaces. If you were upgrading from an older PHP version, you would have non-namespaced classes to look after, potentially using the old style way of creating constructors.

They want to enforce that you are developing within modern PHP principles and that you are also using the new conventions. PHP at this point is committed to removing old-style constructors completely, which we have seen as they are deprecated in PHP 7 and will be removed in a future version.

Finally, the reasoning behind dropping this convention altogether is that it is more error-prone. Using the DRY principles, if one was to change a class name while refactoring, forgetting to change the name of the constructor, it could have subtle and not-so-subtle repercussions.

If you are extending a class and want to call its constructor, it is also more error-prone if their parent class's name changes. For further reading:

https://stackoverflow.com/a/29794401/823549

and

https://stackoverflow.com/a/217876/823549.

PHP constructor executes before arguments for nested variables can be supplied

teh_noob. Listen to me. These words that I'm typing right here. Pretend I'm saying them, and hear the words that are coming out of my mouth. No. NO NO NO NO NO! And no, I don't give a rat's butt how "cool" you think it is.

This is one of those unfortunate scenarios where it would be shorter to list the "right" things about this approach that the "wrong" things. That is to say, your problems are numerous. That being said, I'm going to go over only some of the things that are bad about this idea.

First, let's just discuss OOP in general. What you are doing here is my least favorite thing to see ever: what I call "programming with classes". That is to say, structured programming in the guise of OOP because a class keyword was used. If you're gonna do this, don't bother. Just use functions. This is class abuse plain and simple.

Classes are object blueprints.Objects lend themselves to encapsulation and instantiation. Unless you're really a fan of the Singleton pattern, why create a class that is clearly designed to be instantiated only once? And before you say "But Peter, the Singleton Pattern helps us!!!1one" try to understand that it's actually not all that great. Besides, what you're doing here isn't even a reason people turn to the Singleton pattern in the first place.

Second is the topic of subclasses. Maybe at some point in the future you'll want some popup pages for your site. Or you'll want print-only versions that are more than just CSS-driven. Maybe you'll even want something that's not HTML at all like an RSS feed. What now? How much other work that goes on in this constructor are you going to have to duplicate for these new page types to work? But what if you've already started relying on subclasses to create individual pages? Now you're fucked. Sure, you can go back and hook up the decorator pattern, but why go through all that work when this problem can be avoided by non-stupid class design in the first place?

Thirdly, is the idea of echoing HTML in the first place. I'm fine with echo for a word or two here, a tag or three there. But for large HTML chunks, it's just idiocy. Have the decency to escape to output mode and use HTML that's not locked down in a string. Not only is it easier to edit and read, you can actually work with it in a WYSIWYG should you so desire.

Fourth, this badly, badly breaks the SRP.

Fifth - this kind of ridiculous design leads to the very type of problems you're trying to solve here. Only you don't want to know that the solution is to remove the echo statements from your constructor. Is there a way around it? Sure. In fact, there's even more than one. Do I recommend any of them? No, not really.

Lastly, let's discuss headers. Maybe you haven't learned about them yet. Maybe you have and don't care. But what's going to happen when, 6 months from now, you're working on a problem and you're working inside a method that's 10 calls deep in the stack and you realize a simple header() function will solve your problem. Maybe you need to adjust the cache-control or you need to manually set the response code - whatever. But guess what, you can't. Why? Because your silly constructor outputs to the browser the millisecond it's created.

So, to recap: NO! Unless your actual, ultimate goal is to see some of your very on handiwork on The Daily WTF.

What can I offer besides admonishment? Maybe part of a new direction? Well, debugging output is hard enough in well-built systems, so don't start by shooting yourself in the foot that does it implicitly. All output from your system should be explicit. If you want to make a "page" type of class, that's fine. Just don't do it like that.

class foo
{
protected $title;
protected $headers;

public function setTitle( $title )
{
$this->title = $title;
}

public function addHeader( $header )
{
$this->headers[] = $header;
}

public function sendHeaders()
{
foreach ( $this->headers as $header )
{
header( $header );
}
}

public function printPageHeader()
{
$this->sendHeaders();
?>
<html>
<head>
<title><?php echo $this->title; ?></title>
</head>
<body>
<?php
}

public function printPageFooter()
{
?>
</body>
</html>
<?php
}

public function printPage()
{
$this->printPageHeader();
$this->printPageFooter();
}
}

$p = new foo;
$p->setTitle( 'Just Testing' );
$p->addHeader( 'Cache-control: no-cache' );
$p->printPage();


Related Topics



Leave a reply



Submit