Does/Why php forces you to use the object constructor - php

I have been doing some research on objects in PHP. All the examples I have seen use the object constructor even on their own objects. Does PHP force you to do this and if so why?
For example:
<?php
class Person {
public $isAlive = true;
public $firstname;
public $lastname;
public $age;
public function __construct($firstname, $lastname, $age) {
$this->firstname = $firstname;
$this->lastname = $lastname;
$this->age = $age;
}
public function greet() {
return "Hello, my name is " . $this->firstname . " " . $this->lastname . ". Nice to meet you! :-)";
}
}
// Creating a new person called "boring 12345", who is 12345 years old ;-)
$me = new Person('boring', '12345', 12345);
echo $me->greet();
?>
But if I do this:
<?php
class Person {
public $isAlive = true;
public $firstname;
public $lastname;
public $age;
}
$person->firstname = "John";
echo $person->firstname;
?>
I get a http error code 500.(ie: My code crashed).

You're incorrectly associating the __construct() function with the way in which you instantiate a class/object.
You don't have to use the __construct() function (it's optional). However, before you can use a class's methods, you do have to create an instance of it first.
<?php
class Person {
public $isAlive = true;
public $firstname;
public $lastname;
public $age;
}
$person = new Person(); //Add this line
$person->firstname = "John";
echo $person->firstname;
?>

Because a class definition is exactly that, a definition.
To create an instance of a class (an actual object), you have to instantiate it. You may in fact instantiate many different objects/instances of the same class.
And you don't have to define a constructor method..... but you do have to instantiate using new

There are two ways to work with the class variables.
1. the variable should be public static like:
class Person {
public $isAlive = true;
public static $firstname;
public $lastname;
public $age;
}
Person::$firstname = "John";
echo Person::$firstname;
2. the access to variable via the class object
class Person {
public $isAlive = true;
public $firstname;
public $lastname;
public $age;
}
$person->firstname = "John";
echo $person->firstname;
By the way, PHP can create the object by itself php 5.5 at least.
Your code is not crashing. It just gives a Warning:
Warning: Creating default object from empty value in ...
So WHY?
This is how PHP working with the memory. In a first case the static means that php already allocated memory for the variable and you can work with it. The second case. By using NEW command you give instruction to php to allocate memory and load class into it. So, after the class was created you have an access to the var.
In a third case PHP is calling new Person by itself and give you the warning. I am strongly not recommend to count on php default behavior. ALWAYS create an object in explicit way

Related

Visibility Modifiers [duplicate]

Shouldn't it generate error when i try to set the value of a property from the extended class instead of a base class?
<?php
class first{
public $id = 22;
private $name;
protected $email;
public function __construct(){
echo "Base function constructor<br />";
}
public function printit(){
echo "Hello World<br />";
}
public function __destruct(){
echo "Base function destructor!<br />";
}
}
class second extends first{
public function __construct($myName, $myEmail){
$this->name = $myName;
$this->email = $myEmail;
$this->reveal();
}
public function reveal(){
echo $this->name.'<br />';
echo $this->email.'<br />';
}
}
$object = new second('sth','aaa#bbb.com');
?>
Private variables are not accessible in subclasses. Thats what the access modifier protected is for. What happened here is that when you access a variable that doesn't exist, it creates one for you with the default access modifier of public.
Here is the UML to show you the state:
Please note: the subclass still has access to all the public and protected methods and variables from its superclass - but are not in the UML diagram!

Why is PHP private variables working on extended class?

Shouldn't it generate error when i try to set the value of a property from the extended class instead of a base class?
<?php
class first{
public $id = 22;
private $name;
protected $email;
public function __construct(){
echo "Base function constructor<br />";
}
public function printit(){
echo "Hello World<br />";
}
public function __destruct(){
echo "Base function destructor!<br />";
}
}
class second extends first{
public function __construct($myName, $myEmail){
$this->name = $myName;
$this->email = $myEmail;
$this->reveal();
}
public function reveal(){
echo $this->name.'<br />';
echo $this->email.'<br />';
}
}
$object = new second('sth','aaa#bbb.com');
?>
Private variables are not accessible in subclasses. Thats what the access modifier protected is for. What happened here is that when you access a variable that doesn't exist, it creates one for you with the default access modifier of public.
Here is the UML to show you the state:
Please note: the subclass still has access to all the public and protected methods and variables from its superclass - but are not in the UML diagram!

PHP Class as a Parameter of another class

I'm sorry for what is probably an easy question, but I'm having trouble finding anything about it on the web. I have two classes, for the purposes of this post let's call them user and address, looking like this:
class user {
public $firstName;
public $lastName;
public $address;
}
class address{
public $streetAddress;
public $streetName;
public $city;
public $state;
public $zip;
}
In this case, I want the $address parameter in the user class to be of type "address" defined by the second class. Can I do this in PHP? My end goal is to be able to consume properties like this:
$userZip = $user->address->zip;
Am I on the right track or way off?
Try like this;
<?php
class user {
public $firstName='bulent';
public $lastName ='kocaman';
public $address;
public function __construct()
{
$this->address = new address();
}
}
class address{
public $streetAddress=1;
public $streetName=2;
public $city=3;
public $state=4;
public $zip=5;
}
$user = new user();
print_r($user->address->zip);
?>
or
<?php
class user extends address{
public $firstName='bulent';
public $lastName ='kocaman';
}
class address{
public $streetAddress=1;
public $streetName=2;
public $city=3;
public $state=4;
public $zip=5;
}
$user = new user();
print_r($user->zip);
?>
$address = new $address();
I believe this is what you're looking for.
In PHP variable types are defined by the data they are assigned to. If you want $address in class 1 to be of type $address (class 2) then all you have to do is assign it to an instance of $address and it will take on that type. You will then be able to access any of the $address properties by using:
$user->address->zip
In short, yes you are on the right track. Look into adding constructors to your classes.

Passing parameter for parent::__constructor() function while instantiating an object in php

Hello everybody I'm very new to Object Oriented Programming in php. So sometimes i need help while learning OOP in PHP.
Here's a class named parentClass i have with a few method and properties like:
class parentClass
{
public $fname;
public $lname;
public $age;
function __construct($title, $firstName, $lastName, $age,$address)
{
$this->title = $title;
$this->fname = $firstName;
$this->lname = $lastName;
$this->age = $age;
$this->address = $address;
}
public function getFullName()
{
return $this->fname . " " . $this->lname. " ". $this->address;
}
}
I also have a child class named childClass which extends parentClass with few another properties and methods and also have another _constructor function in it. And then I Called parentClass's method and properties with parent::__construct
class childClass extends parentClass
{
function __construct($title1, $firstName1, $mainName1, $age1)
{
parent::__construct($title, $firstName, $lastName, $age, $address)
$this->title1 = $title1;
$this->fname1 = $firstName1;
$this->lname1 = $mainName1;
$this->age1 = $age1;
}
function getFullName1()
{
return $this->fname1 . " " . $this->lname1 . " ". $this->address;
}
}
So now I have to pass argument to parentClass's construcotr function's parameter. And I want getFullName1 method to return data with address.
if I write:
$obj = new childClass("title", "Rohim", "Uddin", 50);
Here i can pass argument in only childClass's __constructor function parameter.
My question is where to pass argument for parentClass's construcotr function's parameter? more specific for $address parameter;
Thanks in advance. And I'm sorry for any mistake.
First a little explaination of what inheritence means. The fact here is that childClass is an instance of parentClass.
So what does that mean? That means that childClass can use all the variables and methods of parentClass as long the access modifier is public or protected.
You choosed the create public variables, thus that mean that you can use the variables defined in parentClass in your childClass.
That means this will work perfecly fine:
$instance = new childClass("Title","Firstname","Lastname",etc.);
echo $instance->fname; //echo's "Firstname" (according to the code below)
If you use inheritance, the child constructor need to receive the parameters you want to pass through the parent's constructor.
Your almost there, i putted some comments in the code below:
class parentClass
{
//Create the title variable if you want to use it here
public $title;
public $fname;
public $lname;
public $age;
//Create the address variable if you want to use it here
public $address;
function __construct($title, $firstName, $lastName, $age,$address)
{
$this->title = $title;
$this->fname = $firstName;
$this->lname = $lastName;
$this->age = $age;
$this->address = $address;
}
public function getFullName()
{
return $this->fname . " " . $this->lname. " ". $this->address;
}
}
class childClass extends parentClass
{
//It's not necessary to add an `1` or something else to this parameters. Just give them clean names.
//If you want to pass the `$address` variable through the constructor you should add this parameter to this constructor. Since it's the constructor the variable won't be filled elsewhere.
function __construct($title, $firstName, $lastName, $age, $address)
{
parent::__construct($title, $firstName, $lastName, $age, $address)
//This code is too much. In the line above you already passed the variables to the parent constructor. There they are handled by the parents constructor.
//As i explained above you can access these variables, thus it makes no sence to create new variables here or to override the just-setted variables.
/*$this->title1 = $title1;
$this->fname1 = $firstName1;
$this->lname1 = $mainName1;
$this->age1 = $age1;*/
}
//Why you write this function here? Because `childClass` inherits from `parentClass` you can just use the methods of `parentClass`. If you call `childClass->getFullName()` the `getFullName` function in `parentClass` will be executed.
//It will return the same values as you are returning here. Just leave this function. Only create this function if you want to override the default `parentClass->getFullName` behaviour. Then leave the 1 so it will be `getFullName` instead of `getFullName1`
/*function getFullName1()
{
return $this->fname1 . " " . $this->lname1 . " ". $this->address;
}*/
}
So what's happening at the end?
$instance = new childClass("My Title", "Stefan", "Pols", 25, "My Adress 1");
//`childClass` constructor is called here.
//The first line (`parent::__construct`) will pass the variables to the parentClass. There they are set to the right variables.
echo $instance->getFullName();
//Compiler tries to find the method `getFullName()` in `childClass`. It doesn't exist.
//Compiler sees it inherits from `parentClass` so it's going to search the method `getFullName()` in `parentClass`
//It does exist. Since we setted the variables during the creation of the `$instance` object (through the constructor) this function will return the right values.
Output: `$this->fname . " " . $this->lname. " ". $this->address;` > Stefan Pols My Adress 1

variable creation inside classes

I am following a tutorial on dependency injection. My issue is that I do not understand how some of the variables are being formulated within the classes. Within class Author we have $firstname and $lastname. Within class Question we have $author and $question. Then magically(?) we have within the class Question constructor we get $authorFirstname and $authorLastname.
I don't get it - it's like they have been concatenated, but that can't be, right ?? But then the $authorFirstname and $authorLastname have not been declared within class Question.
So, Question: how does the author get to the $authorFirstname and $authorLastname - or am I over thinking this ??
class Author {
private $firstName;
private $lastName;
public function __construct($firstName, $lastName) {
$this->firstName = $firstName;
$this->lastName = $lastName;
}
public function getFirstName() {
return $this->firstName;
}
public function getLastName() {
return $this->lastName;
}
}
class Question {
private $author;
private $question;
public function __construct($question, $authorFirstName, $authorLastName) {
$this->author = new Author($authorFirstName, $authorLastName);
$this->question = $question;
}
public function getAuthor() {
return $this->author;
}
public function getQuestion() {
return $this->question;
}
}
You're overthinking.
you notice, __construct($question, $authorFirstName, $authorLastName)...
construct is a special function that runs when a new object of that class is created.
$authorFirstName and $authorLastName are just variables to be passed to the Question constructor function, aka
$question = new Question($questioninfo,'William','Shakespeare');
(in this case, $authorFirstName = William, $authorLastName = Shakespeare)
They only get used within the scope of the __construct() function, which in this case instantiates a new Author. so if the input was as above, this will happen inside the constructor of Question:
$this->author = new Author('William', 'Shakespeare');
and those variables will be handled by Author's constructor, as $firstName and $lastName... make sense?
The Question ctor is an example of a hidden dependency, not showing how dependency injection works:
public function __construct($question, $authorFirstName, $authorLastName) {
$this->author = new Author($authorFirstName, $authorLastName);
$this->question = $question;
}
As this code shows, the parameters $authorFirstName, $authorLastName are used to create the Author dependcy inside Question. Therefore the dependency is not injected.
Instead, the author should be injected:
public function __construct($question, Author $author) {
$this->author = $author;
$this->question = $question;
}
The Question is only interested in compositing an Author, there is no need that the Question needs to create an Author.
I hope this also illustrates how parameters work.

Categories