I was trying to figure out if I can instantiate a class within its own constructor and I came across this:
Why Can You Instantiate a Class within its Definition?.
Then I tried the same thing in PHP:
Class someClass {
function __construct() {
$objNew = new someClass();
$objNew->doit();
}
function doit() {
echo "Do it man!\n";
}
}
$oNew = new someClass();
Everytime I tried to run this I got a "Segmentation Fault" error.....
With reference to the above code and even the link posted above, I want to think that instantiating a class within its own constructor would cause an infinite number of objects to get created (until the server crashes, of course!).....any thoughts on what is going on above? Why is it ok to do this in Java and (perhaps) not in PHP?
It's not the same thing. On the question Why Can You Instantiate a Class within its Definition?, a static method is used to instantiate his class. Static methods are stored with the class definition (like a blueprint) inside the heap memory and do not require to be instantiated.
You could create a static method, and this one will have to create a new instance of your class:
Class someClass {
function __construct() {
$this->doit();
}
static function createSomeClass() {
return new someClass();
}
function doit() {
echo "Do it man!\n";
}
}
$oNew = someClass::createSomeClass();
Php is not compiled but interpreted. Java is compiled and after this executed. So the class itself is not yet all defined and you call it again in php so this throws an error.
Below is the right solution for you
<?php
Class someClass {
function __construct() {
$this->doit();
}
function doit() {
echo "Do it man!\n";
}
}
$oNew = new someClass();
?>
If all you want to do is call that method when object is instantiated. Then, there's no meaning of doing this $objNew = new someClass();. Its useless. Simply, do this:
class someClass {
function __construct() {
$this->doit();
}
function doit() {
echo "Do it man!\n";
}
}
$oNew = new someClass();
Related
I'm absolutely sure this has been asked before, but I cannot find it anywhere.
So I have two classes. A and B
class classA
{
public $var1;
public $classbVar;
public function init()
{
// This is here because other script is run before it is called
// in the live code.
// it basically checks that the file exists. There is a reason for this.
if (file_exists('classB.php'))
{
require_once('classB.php');
}
else
{
echo "An error has occurred loading the second class.";
}
$this->var1 = "something";
$this->classbVar = new classB
echo $this->classbVar->doSomething();
}
}
In a separate file
class classB extends classA
{
public function doSomething()
{
echo $this->var1;
}
}
In a third file, I'm calling classA and running the init function. This is not real code, but identical to what I have written.
So why doesn't this work. if I VAR_DUMP I get null.... What have I done wrong or misunderstood?
LET ME BE MORE CLEAR:
There is a third file which calls classA as below;
require_once('classA.php')
$classA = new classA;
$classA->init();
My apologies for any confusion, I did this on the fly a little bit, as I am sure I am missing something simple here. Surely the way I am trying to do this will work somehow.
There are 2 problems here that cause your output to be null:
You are generating a new $classA object and any values you set on that, will not automatically be set on the $classbVar object as that is a completely different object of a class that just extends the A class, not the $classA object you have just generated. With the exception of a static property of course...
If you want to set the value of a property in an object, you need $this->var1 instead of $var1. Note if you set the value in your $classA object, it is still not set for the $classbVar object.
Put require_once above class declaration (this is not big issue but it's more clear)
Assign variables to class properties because they way you did the scope of them is only within the method.
$var1 = "something";
should be changed to
$this->var1 = "something";
Also the class values are not shared unless they are declared as static. So to access the properties from parent class you can do following:
class classA
{
public $var1;
public function init()
{
$this->var1 = "something";
}
}
// other file
require_once("A class location");
class classB extends classA
{
public function doSomething()
{
echo $this->var1;
}
}
$b = new classB();
$b->init();
$b->doSomething();
or more clean way:
class A
{
protected $var1;
public function __construct()
{
$this->var1 = "something";
}
}
// other file
require_once("A class location");
class B extends A
{
public function doSomething()
{
return $this->var1;
}
}
$b = new B();
echo $b->doSomething();
// or shorter syntax
echo {new B()}->doSomething();
Instead of using require_once() it's better to use PSR-4 autoloader.
I have a class setup like this:
class myClass {
public function __construct() {
echo 'foo bar';
}
}
To run it, I can simply do:
$object = new myClass;
Is there any way to run the class so __construct initiates without creating a new variable with the class object.
For example, a basic function can be run with:
functionname();
Don't call __construct directly. If you need something in the constructor to occur but you don't want an object created as a result, then use a static method.
class Thing{
public static function talk(){echo "I talk";}
}
Thing::talk(); // 'I talk'
Static methods can be called without the need for an object instance of the class.
__construct is part of a special group of methods in PHP, called Magic Methods. You don't call these directly, but PHP will call them when some event occurs. For instance when you call new on a class, __construct is executed.
Another example: if you try to get a property that doesn't exist, __get will be executed (if found):
Class Thing{
public property $name = 'Berry';
public function __get($propertyName){
return "$propertyName does not exist!";
}
}
$t = new Thing();
echo $t->name; // 'Berry'
echo $t->weight; // 'weight does not exist!';
You can try something like this if you want to avoid static:
(new MyClass)->myFunction();
I have no idea why you need this but you don't need to create a variable. You can just create object without store it anywhere.
class myClass {
public function __construct() {
echo 'foo bar';
}
}
new myClass();
In this case only the constructor will be call.
// in class
public function test () {
$this->__invoke();
}
$inst->test();
This test runs without any error.
My question: is there some reason why this should not be done? Are there any corner cases, hidden caveats, or does it behave like any regular function/method?
That should not work since there is no __invoke() method in your class:
class SomeClass {
public function test()
{
$this->__invoke();
}
}
$inst = new SomeClass();
$inst->test();
http://3v4l.org/JOBXn.
If you implement __invoke(), that should work:
class SomeClass {
public function __invoke()
{
var_dump('Invoke!');
}
}
$inst = new SomeClass();
$inst();
http://3v4l.org/mpG5d.
Magic methods can be called directly as you can see in the second test, but in my opinion it is not a good idea since they are some kind of hooks and their code could be executed unexpectedly.
Is there any difference in constructor or unified constructor. I have a class which have a constructor and a unified constructor. When i intialise object of the class then unified constructor call why not normal constructor.
<?php
class test {
function __construct() {
print "In BaseClass constructor\n";
}
function test() {
echo 'Class loeaded';
}
}
$obj = new test();
?>
OUTPUI
In BaseClass constructor
PHP Version 5.2.6
Since PHP 5, the best way to declare a constructor method in a class is to use the standardized
__construct()
So if you have
class myA {
public function __construct() {
echo "hello construct myA";
}
public function myA() {
echo "hello basic way myA";
}
}
$myA = new myA();
It will echo
hello construct myA
because the __constructor() has priority
But, for compatibility reason, the old way may work if there is not __construct() method.
And:
class myA {
//public function __construct() {
// echo "hello construct A";
//}
public function myA() {
echo "hello basic way myA";
}
}
$myA = new myA();
will give you:
hello basic way myA
In all cases, I advise you to use __construct()
the old constructor (method with class name) is only there for compatibility reasons. so if you have the new constructor (__construct) in the class php won't bother to call the old one.
edit
interesting note is that calling parent::__construct when the class being extended has only the old constructor type will still work (it becomes like a alias to the real constructor)
Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.
Read documentation of constructor (link)
Instances of classes are created using the new keyword. What happens during the new call is that a new object is allocated with its own copies of the properties defined in the class you requested, and then the constructor of the object is called in case one was defined. The constructor is a method named __construct(), which is automatically called by the new keyword after creating the object. It is usually used to automatically perform various initializations such as property initializations. Constructors can also accept arguments, in which case, when the new statement is written, you also need to send the constructor the function parameters in between the parentheses.
In PHP 4, instead of using __construct() as the constructor’s name, you had to define a method with the classes’ names, like C++. This still works with PHP 5, but you should use the new unified constructor naming convention for new applications.
We could pass the names of the people on the new line in the following class example :
class Person {
function __construct($name)
{
$this->name = $name;
}
function getName()
{
return $this->name;
}
private $name;
};
$judy = new Person("Judy") . "\n";
$joe = new Person("Joe") . "\n";
print $judy->getName();
print $joe->getName();
Tip: Because a constructor cannot return a value, the most common practice for raising an error from within the constructor is by throwing an exception.
According to documentation As of PHP 5.3.3, methods with the same name as that of class will no longer be treated as constructor .. They are like regular methods ...
<?php
class myclass
{
public function myclass()
{
// treated as constructor in PHP 5.3.0-5.3.2
// treated as regular method as of PHP 5.3.3
}
}
?>
`
For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, and the class did not inherit one from a parent class, it will search for the old-style constructor function, by the name of the class.
It means that there if you have constructor myclass() and __construct .. then __construct will be searched for first and taken as constructor instead of myclass()
class myclass
{
public function myclass()
{
echo 'hello';
}
function __construct() {
print "new constructor"
}
}
$obj = new myclass(); // will echo new constructor
I have an idea of using this syntax in php. It illustrates that there are different fallback ways to create an object
function __construct() {
if(some_case())
$this = method1();
else
$this = method2();
}
Is this a nightmare? Or it works?
Or it works?
It doesn't work. You can't unset or fundamentally alter the object that is being created in the constructor. You can also not set a return value. All you can do is set the object's properties.
One way to get around this is having a separate "factory" class or function, that checks the condition and returns a new instance of the correct object like so:
function factory() {
if(some_case())
return new class1();
else
return new class2();
}
See also:
Breaking the constructor
PHP constructor to return a NULL
Why not to do something more common like:
function __construct() {
if(some_case())
$this->construct1();
else
$this->construct2();
}
You can just create class methods method1 and method2 and just write
function __construct() {
if(some_case())
$this->method1();
else
$this->method2();
}
You can make factory method.
Example:
class A {}
class B {}
class C {
function static getObject() {
if(some_case())
return new A();
else
return new B();
}
}
$ob = C::getObject();
It sounds a little bit like the Singleton class pattern.
See #Ivan's reply among others for the correct syntax for what it looks like you're trying to do.
However, there are is another alternative - use a static method as an alternative constructor:
class myclass {
function __construct() { /* normal setup stuff here */}
public static function AlternativeConstructor() {
$obj = new myclass; //this will run the normal __construct() code
$obj->somevar = 54; //special case in this constructor.
return $obj;
}
}
...
//this is how you would use the alternative constructor.
$myobject = myclass::AlternativeConstructor();
(note: you definitely can't use $this in a static method)
If you want to share some functions, do some like
class base{
'your class'
}
class A extends base{
'your class'
}
class B extends base{
'your class'
}
And call like
if(some_case())
$obj = new A();
else
$obj = new B();