I'm reading few books about PHP and getting stared to grab the basics. I came across “instantiated” and “initialised” words. I can not find an example which explains them.
What is the difference between “instantiated” and “initialised” in PHP ? What do they mean ? How to use them ? What's the purpose of using them ?
Provide an example if possible.
You instantiate an object from a class. I.e. you create an instance (hence the name). In code:
$obj = new SomeClass();
You initialise a variable, which means "giving it its initial (hence the name) value".
$var = "someValue";
In fact, when you instantiate, you also often initialise it (in the constructor). For example:
// this instantiates an object of class 'SomeClass' and
// initialises it with "somevalue"
$obj = new SomeClass("someValue");
Instantiation is a object-oriented programming term. Initialisation is used in all languages. Both terms are certainly not limited to PHP.
Instances are where you have allocated memory for the variable but may or may not have placed a value in there.
Initialized is where you have allocated memory as well as stored an intial value to it as well.
Just adding after reading Barts Answer that object oriented programming usually refers to instances in terms of objects being allocated memory while variables are said to be initialised which means allocated memory and assigned a value as well.
So for example
int $intarray=new Array(); // Instance created
while
int $intarray= new Array({1,2,3}); // instance created and initialised
When you define a class in any object oriented programming language, you create a blue print of an object but the object does not exist. But when you create a copy of that object based on the class or blue print defined, you actually instantiate a class. For example:
//Define a Class called Foo
class Foo {
public $aMemberVar = 'aMemberVar Member Variable';
public $aFuncName = 'aMemberFunc';
function aMemberFunc() {
print 'Inside `aMemberFunc()`';
}
}
// Create an object of type Foo * Instantiate Foo
$foo = new Foo;
Now for Initialised, consider any variable. When you declare a variable, it is there but does not hold any meaningful value. So, the process of assigning a value for the first time to a variable is known as intialisation. Initialisation may happen at the time you declare a variable or may be later programmatically.
Just declare a variable:
var $newVariable;
Intialise the above variable:
$newVariable = "This is intialisation";
Declare and intialise a variable:
var $intialisedVar = "This var is declared and intialised";
Just to add another point in intialisation, see the variables in the class above. These variables will be intialised automatically as soon as you instantiated an object.
Hope this helps.
Related
Fairly new to classes in PHP, so bear with me.
class processRoutes
{
//Next line works
private $doc = "works as as string";
//Next line does not work, "Parse error: syntax error, unexpected T_NEW"
private $doc = new SimpleXMLElement('routingConfig.xml', null, true);
private function getTablenames()
{
//do stuff
}
}
I'm trying to ultimately utilize the SimpleXMLElement object within my class, among several private functions. What is the correct method for going about this, and why doesn't my current method work?
You need to do this in your constructor, as this can't be evaluated at this stage of script parsing. 'Simple' values, as strings, bools and numeric values will work though.
class processRoutes
{
//Next line works
private $doc = "works as as string";
private $doc;
public function __construct()
{
$this->doc = new SimpleXMLElement('routingConfig.xml', null, true);
}
// ....
}
You're attempting to initialise a property with an object instance, but you're only allowed to initialise variables with constants that can be determined at "compile time".
From PHP Manual - Properties
This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.
Any initialisation that depends on "run time" knowledge will need to be executed either
in a constructor (refer #Dan-Lee's answer on how to implement this) that operates on $this->doc,
from within eg a "initialiser" function called from your constructor (you might do this to keep the "initialisation" steps distinct from other "real work" that might be done from your constructor), or
manually by your class's consumer. The consumer may operate
directly on the properties or your object (eg myProcessRoutes->doc = 'some other string'),
via a function call to your object eg myProcessRoutes.initialise_doc('some other string'), or
via a setter on your object - I'll let you research those, as I've not used these in PHP! ;-)
(Although it's arguable/philosophical if these approaches that occur later than instantiation/constructor are really initialisation).
The point of class constructors/destructors is to provide a "hook" by which the object instance can be initialised/disposed as required.
You might just need to create some specific new instances as per your example, in which case you don't need to accept any input to the constructor from the consumer.
Or, you might need to accept some values in order for your class to be set up properly. This is exactly what's happening in your example code above, when you're calling
private $doc = new SimpleXMLElement('routingConfig.xml', null, true);
(that is, you're passing the values of 'routingConfig.xml', null and true in to your new instance of SimpleXMLElement, so that this instance's constructor can initialise the instance using the values you passed to it, ready for use).
anytime you want to reference a class's variable, use the keyword $this
public function getTablenames()
{
$my_new_variable = $this->doc; // Transfers the $doc variable
}
I was looking through the PHP documentation and saw several comments where a variable was initialized outside of a class's constructor, similar to the following:
classMyClass {
private $count = 0;
public function __construct() {
//Do stuff
}
}
In PHP Objects, Patterns, and Practice, the author recommends using constructs only for the initialization of properties, deferring any heavy lifting or complex logic to specialized methods. This tutorial (a quick example that I found on Google) also recommends using constructors to initialize properties: http://www.killerphp.com/tutorials/object-oriented-php/php-objects-page-3.php.
Why would you want to initialize a variable outside the constructor? Is this just sloppy coding, or is there a reason to do something like this? I have to say that until recently, I initialized default values outside the constructor, and there doesn't seem to be any programmatic advantage of one way over the other.
When you initialize a variable outside of the constructor, it must be initialized as a constant. You can't do any operation to initialize it. Thus, the initial value of that member is actually a part of the class signature.
For example, this is invalid:
private $var = $othervar;
private $var = func();
You could do it in the constructor as well, but it would be a bit more verbose and add some clutter to the constructor unless there was some sort of logic going on.
More a comment than an answer, but please elaborate here a little:
Since it is recommended to use constructors for property initialization only,
Who says this and why? I assume the only relates to something else than property definitions with default values.
An answer part:
By default in PHP variables do not need to be defined because variables are then defined when first accessed in a write context. All variables, including undefined ones contain NULL (Demo):
class A {}
$a = new A;
var_dump($a->property); # NULL
Introducing class variables (properties) PHP then allowed to actually define variables. Those still return NULL by default, but they are defined (Demo):
class A {
public $property;
}
$a = new A;
var_dump($a->property); # NULL
In the next step of the evolution, this language construct also allows to specify a constant expression. That is constant because definition is compile-time (not run-time as the when the constructor is invoked). An example (Demo):
class A {
public $property = 'hello';
}
$a = new A;
var_dump($a->property); # string(5) "hello"
As this is compile- but your constructor run-time, I find it hard to compare both feature with another. Also it's not clear why you say that initializing via the constructor is recommended.
Far from sloppy... it's good programming practice. As you would also do in Java/C++, it just sets them up, and then you can do any initialisation in the constructor - usually to sent them to non-defaults as such.
In my quest in trying to learn more about OOP in PHP. I have come across the constructor function a good few times and simply can't ignore it anymore. In my understanding, the constructor is called upon the moment I create an object, is this correct?
But why would I need to create this constructor if I can use "normal" functions or methods as their called?
cheers,
Keith
The constructor allows you to ensure that the object is put in a particular state before you attempt to use it. For example, if your object has certain properties that are required for it to be used, you could initialize them in the constructor. Also, constructors allow a efficient way to initialize objects.
Yes the constructor is called when the object is created.
A small example of the usefulness of a constructor is this
class Bar
{
// The variable we will be using within our class
var $val;
// This function is called when someone does $foo = new Bar();
// But this constructor has also an $var within its definition,
// So you have to do $foo = new Bar("some data")
function __construct($var)
{
// Assign's the $var from the constructor to the $val variable
// we defined above
$this->val = $var
}
}
$foo = new Bar("baz");
echo $foo->val // baz
// You can also do this to see everything defined within the class
print_r($foo);
UPDATE:
A question also asked why this should be used, a real life example is a database class, where you call the object with the username and password and table to connect to, which the constructor would connect to. Then you have the functions to do all the work within that database.
The idea of constructor is to prepare initial bunch of data for the object, so it can behave expectedly.
Just call a method is not a deal, because you can forget to do that, and this cannot be specified as "required before work" in syntax - so you'll get "broken" object.
Constructors are good for a variety of things. They initialize variables in your class. Say you are creating a BankAccount class. $b = new BankAccount(60); has a constructor that gives the bank account an initial value. They set variables within the class basically or they can also initialize other classes (inheritance).
The constructor is for initialisation done when an object is created.
You would not want to call an arbitrary method on a newly created object because this goes against the idea of encapsulation, and would require code using this object to have inherent knowledge of its inner workings (and requires more effort).
Why does PHP require you to explicitly write $this? I would understand if you had to use $this here:
function foo($bar) {
$this->bar = $bar;
}
But you must write it explicitly in verbose code that looks like this:
$this->var3 = globalFun($this->var, $this->var2[$this->anotherVar], $this->method());
as opposed to:
$var3 = globaFun($var, $var2[$anotherVar], method());
So what is the point of $this?
Additional Bonus Question:
Why do we have to differentiate static references and instances? Why do we need:
static function getValue() {
return self::value;
}
Can't PHP find out at runtime if the variable/method in question is static? Now if I want to change a method from static to non-static, I have to replace all those self:: with $this-> (and vice-versa).
Wouldn't it be better if we had a $this that behaves like it does in Java?
Since this was re-opened, I'll post here my answer, as promised.
TL;DR version If it were not required to qualify a member access, there would be not only performance penalties, but the same line of code could simultaneously signify a field access and a local variable access, depending on the code path.
Full version
In PHP, there's always one symbol table active at the table. This is either the global symbol table or a function/method local symbol table (which by the way, are lazily built). Superglobals and optimizations like compiled variables aside, when a variable $var is requested, it is looked up in the current symbol table. Since the object properties live not on the symbol tables, but instead on either in the objects (the instance properties) or the structure associated the class (the static properties), a lookup for $var can never return a property.
To bring a given variable to the function scope, you must explicitly signal your intention by creating a reference. Examples:
$myglobal = 7;
class A {
private $prop;
public function meth() {
global $myglobal; //bring a global to the current scope
$prop =& $this->prop; //brings a property to the current scope
$local = 4;
$lambda = function () use (&$local) { };
}
}
Obviously, this is just a more sophisticated way to phrase what currently happens. The question is why this behavior?
After all, in Java we only have to type this.prop when there's a local variable called prop hiding the property. Why is this not a good option for PHP?
I can think of several reasons.
The object properties are determined at runtime
PHP has something called "dynamic properties". You can assign new properties to objects at runtime. In fact given two objects of the same class, one can have a given property $a and while the other doesn't. Example:
$obj1 = new stdClass();
$obj2 = new stdClass();
$obj1->a = 7;
In PHP, the defined local variables are determined at runtime
Variables do not have to be declared; consequently, depending on the code path, at some point a variable may or may not be defined. To add insult to the injury, we also have the monster called "variable variables". Example:
class A {
private $g = 3;
public function func($varname) {
if (rand(1,2) == 1) {
$g = 4; //no block scope; the scope is the function's
}
$$varname = 5; //god knows what's happening here
//if local variables hid properties, we'd have trouble
}
}
In Java, a given identifier may also represent, inside the same function, a local variable and a property, but:
Not within the same block (in PHP, all blocks in a function share exactly the same scope).
You get a warning if you're hiding a property.
Crucially, in any given occurrence of an identifier, it's either a property or a local variable, it can't sometimes be one and other times the other.
Consequences
Owing to these facts, it would be impossible to determine at compile time if $var referred to a local variable or to a property. Consequently:
At runtime, every time a variable occurred, it would have to looked up first in the local symbol table, then in the instance properties table, and finally in the static properties list, or any other order (since there can't be an instance and a static property with the same name and static properties need to be declared, there would be some optimization potential here, but the point stands). This means a symbol would have, in the worst case, would have to be looked up in three different places. This is bad from a performance perspective.
A given symbol occurrence could mean different things on different occasions. This is a recipe for disaster.
Okay, so let's remove the need for writing $this everywhere. Take a look at this situation:
class Foo {
public function setBar($value) {
$bar = $value;
}
}
$foo = new Foo();
$foo->setBar('some value');
Is $bar a local variable or a member of $foo?
There has to be some differentiation. They could have allowed declaration of local variables with the var keyword, but that would not have been backwards-compatible and would have been very confusing to people upgrading from older versions of PHP.
Same thing applies to self::. How does the interpreter know whether the function you wanted to call is global or specific to the class?
PHP was not OOP.
Now it is, but with side effects.
Actually, I know people who use this. in Java even where unnecessary because they feel it creates clearer code ;) I don't have a really definite answer, but I guess that, internally, getting $var would always have to be translated to $this->var. So it's not like someone intentionally made things more complicated by forcing us to do $this->var, but just decided to not implement the $var shortcut. If that helps in any way, I don't know ;)
In my quest in trying to learn more about OOP in PHP. I have come across the constructor function a good few times and simply can't ignore it anymore. In my understanding, the constructor is called upon the moment I create an object, is this correct?
But why would I need to create this constructor if I can use "normal" functions or methods as their called?
cheers,
Keith
The constructor allows you to ensure that the object is put in a particular state before you attempt to use it. For example, if your object has certain properties that are required for it to be used, you could initialize them in the constructor. Also, constructors allow a efficient way to initialize objects.
Yes the constructor is called when the object is created.
A small example of the usefulness of a constructor is this
class Bar
{
// The variable we will be using within our class
var $val;
// This function is called when someone does $foo = new Bar();
// But this constructor has also an $var within its definition,
// So you have to do $foo = new Bar("some data")
function __construct($var)
{
// Assign's the $var from the constructor to the $val variable
// we defined above
$this->val = $var
}
}
$foo = new Bar("baz");
echo $foo->val // baz
// You can also do this to see everything defined within the class
print_r($foo);
UPDATE:
A question also asked why this should be used, a real life example is a database class, where you call the object with the username and password and table to connect to, which the constructor would connect to. Then you have the functions to do all the work within that database.
The idea of constructor is to prepare initial bunch of data for the object, so it can behave expectedly.
Just call a method is not a deal, because you can forget to do that, and this cannot be specified as "required before work" in syntax - so you'll get "broken" object.
Constructors are good for a variety of things. They initialize variables in your class. Say you are creating a BankAccount class. $b = new BankAccount(60); has a constructor that gives the bank account an initial value. They set variables within the class basically or they can also initialize other classes (inheritance).
The constructor is for initialisation done when an object is created.
You would not want to call an arbitrary method on a newly created object because this goes against the idea of encapsulation, and would require code using this object to have inherent knowledge of its inner workings (and requires more effort).