variable creation inside classes - php

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.

Related

Use of __construct or setVar() [duplicate]

I have been searching for this online, but I can't seem to find something that is clear enough for me to understand. I have seen "similiar" questions on here about this in Java.
class animal{
private $name;
// traditional setters and getters
public function setName($name){
$this->name = $name;
}
public function getName(){
return $this->name;
}
// animal constructors
function __construct(){
// some code here
}
// vs
function __construct($name){
$this->name = $name;
echo $this->name;
}
}
$dog = new animal();
$dog->setName("spot");
echo $dog->getName();
// vs
$dog = new animal("spot");
Should I declare and access my private fields through setters and getters or through the constructor?
Which one is the best practice?
I understand the purpose of a constructor(maybe not), but what is the point of having a constructor if I can declare and access my private fields through setters and getters?
Please note...this is my first time using OOP with web development and PHP, and I'm trying to learn by getting my hands "dirty" by writing some code in order for me to understand certain things in OOP. Please keep it simple.
It is more a matter of semantics than best practice per say.
In your example, your buisness logic may determine that an animal always needs a name.
So it makes sense to construct the object with a name. If you do not want to allow
an animal's name to be changed, then you don't write a setter.
i.e.
class Animal
{
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}
You may have other properties that an animal doesn't have to have, like an owner
that you only write a getter/setter for i.e.
class Animal
{
private $name;
private $owner;
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
public function setOwner($owner)
{
$this->owner = $owner
}
}
But if you find that you are always creating an animal with an owner at the same time
you may want to put that in the contructor signature for convenience
class Animal
{
private $name;
private $owner;
public function __construct($name, $owner = null)
{
$this->name = $name;
$this->owner = $owner;
}
public function getName()
{
return $this->name;
}
public function setOwner(Owner $owner)
{
$this->owner = $owner
}
public function getOwner()
{
return $this->owner;
}
}
If the owner is another class in your application, you can type hint that your constructor
needs an owner of a specific type (class). All of this is used to make it easier for you, or another developer to understand some of the requirements/logic behind your code - as well as potentially catching a bug here or there
class Owner
{
private $name;
public function __construct($name)
{
$this->name = $name;
}
}
class Animal
{
private $name;
private $owner;
public function __construct($name, Owner $owner = null)
{
$this->name = $name;
$this->owner = $owner;
}
public function getName()
{
return $this->name;
}
public function setOwner(Owner $owner)
{
$this->owner = $owner
}
public function getOwner()
{
return $this->owner;
}
}
// Create a new owner!
$dave = new Owner('Farmer Dave');
// a standard php empty object
$otherObj = new \stdClass();
// Create a new animal
$daisy = new Animal('Daisy');
// Farmer dave owns Daisy
$daisy->setOwner($dave);
// Throws an error, because this isn't an instance of Owner
$daisy->setOwner($otherObj);
// Set up Maude, with Dave as the owner, a bit less code than before!
$maude = new Animal('Maude', $dave);
Should I declare and access my private fields through setters and getters or through the constructor?
In situations like this, I ask myself:
Why should I create a method just to hold a one line function? (+Constructor)
How painful is it going to be to refactor two, three, four, five or more getters/setters vs one constructor?(+Constructor)
How hard is it going to be to document two, three, four, five or more getters/setters vs one constructor?(+Constructor)
Is there going to be a default value which will be documented? (+Constructor)
Do I like documentation and expect people to read? (+Constructor)
Will the initial value be undefined?(+Setter)
Is there a set of equivalent forms (shorthand, international, nicknames) which will all be acceptable as syntatically correct for required arguments? (+Setter)
Is there a set of optional arguments with default values? (+Setter)
Is there a common need to stringify and parse the initial value? (+Setter)
Do I dislike documentation and expect people to experiment? (+Setter)
Which one is the best practice?
The Date object seems to be the most complex class in most languages, so its PHP implementation would be a good reference for best practices.
What is the point of having a constructor if I can declare and access my private fields through setters and getters?
A constructor is implicitly invoked upon object instantiation in order to encapsulate the default state of the resulting data structure of its type.
References
DateTime::__construct
date_create
The DateTime class
date_default_timezone_get
date_default_timezone_set
Changes in PHP datetime support
PHP OOP: Accessor and Destructor Methods
Concurrency, part 4: Comparing promises frameworks in different languages – SLaks.Blog
CDD: Context-Driven Development
Depends. Usually one say: If it's a required dependency, use the constructor, if it's optional, use getter/setter.
There is no preference for, or against one of them.
The constructor contains code, that is executed right after the object is created and it should leave the object in a stable and useable state. Thats the idea behind the constructor and it doesn't work in any case, but it should give you an idea, what should go into it.
Note, that you can even implement both constructor arguments and setters for the same property, for example if you want to allow to replace property later.
$bingo = new Dog;
echo $bingo->getName(); // DogHasNoNameException <-- maybe better as constructor argument?
$bingo = new Dog('Bingo');
echo $bingo->getName(); // "Bingo"
$spike = new Dog; // Missing argument
$bingo->setName('Spike'); // Or maybe "rename()" ;)
echo bingo->getName(); // "Spike"
Should I declare and access my private fields through setters and
getters or through the constructor? Which one is the best practice?
Both. It depends on your needs. If need a value in certain fields you add a param to the
__construct()-Method to do so. Or you can also add an optional Param to __construct to give the user the option to set the attribute
I understand the purpose of a constructor(maybe not), but what is the
point of having a constructor if I can declare and access my private
fields through setters and getters?
The contructor should initialize your attributes which need to be initialized.
In my opinion, it is more correct to write setter's & getter's, since then, the number of properties will only grow. And the __construct can then take an array of properties of the names of the keys (property => value), and set them to properties.
1 > That's your chose : if dependency is required, good practise use the constructor, else, use getter.
2 > for the best practise is the first,
Actually, you have a name, for your animal, but if you add a type and sex? and you want to call type, sexe or name separatly, first method is more better than the second.
class animal{
private $name, $type, $sex;
// traditional setters and getters
public function setName($name){
$this->name = $name;
}
public function setSex($sex){
$this->sex = $sex;
}
public function setType($type){
$this->type = $type;
}
public function getName(){
return $this->name;
}
public function getSex(){
return $this->sex;
}
public function getType(){
return $this->type;
}
// animal constructors
function __construct(){
// some code here
}
}
$dog = new animal();
$dog->setName("spot");
$dog->setSexe("male");
$dog->setType("dog");
echo $dog->getName().' is a '.$dog->getType().'('.dog->getSex().')';
3 > that depends first question... BUt Globaly we are always one dependency required, for sample:
class animal{
private $name, $type, $sex;
// traditional setters and getters
public function setName($name){
$this->name = $name;
}
public function setSex($sex){
$this->sex = $sex;
}
private function setType($type){
// if type is string ( cat, dog, lion ) and you want
// to linked string in an id in your database (1, 2, 3...).
// you want to call your database connection ( declared in you constructor)
// and search type id here.
$this->type = $type;
}
public function getName(){
return $this->name;
}
public function getSex(){
return $this->sex;
}
public function getType(){
return $this->type;
}
// animal constructors
public function __construct($type){
// for sample you want to open your database here
this->setType($type);
}
public function __destruct(){
// and you want to close your connection here.
}
}

Getters naming convention

I understand the traditional naming convention for getter methods:
getName();
getAddress();
getAge();
But i dont understand why. I would rather just use the property name as the method as in the following example:
class Person
{
private $name;
private $address;
private $age;
public function __construct($name, $address, $age)
{
$this->name = name;
$this->address = address;
$this->age = age;
}
public function name()
{
return $this->name;
}
public function address()
{
return $this->address;
}
public function age()
{
return $this->age;
}
}
This makes code more fluent to me
i.e. $person->address()
But i get pulled up on code reviews when doing this for not using proper naming conventions.
Is there anything fundamentally wrong with not using get/set prefixes ?
Generally it's good for methods to contain a verb. This way the method's name is more self explanatory.
More info and Source: http://pear.php.net/manual/en/standards.naming.php

PHP undefined index in a class

I know this has been asked before and I have looked at multiple threads on why this would happen but could not understand how mine does not work as other variables defined in the same way and gathered the same way work.
class item{
var $name = "test";
var $id = 3;
function setId($newID){
global $id;
$id = $newID;
}
function getId(){
return $GLOBALS['id'];
}
function setName($newName){
global $name;
$name = $newName;
}
function getName(){
return $GLOBALS['name'];
}
}
That is a snippet of the class as it is really long but duplicate getName and setName for 5/6 more items.
$item[0]->getName();
Would return "test"
$item[0]->getId();
Returns the "Undefined index: id in link to file on line 59" which is the getId() function.
Every function other then getId() works and I have no idea why
EDIT - this question has been answered I am waiting to be able to accept an answer. $this worked for the variable to return (even though I'm still not sure why it would even though the 5 or 6 others would)
Your understanding of variable scope within a class is wrong. Setters and getters are, usually, to modify and fetch private or protected properties. Assigning a property with var automatically gives them a public scope.
In a class, you don't need to use global - in fact, using global is bad practice anyway. You can reference class properties with $this.
For example;
class item {
private $name = "test";
private $id = 3;
function setId($newID){
$this->id = $newID;
}
function getId(){
return $this->id;
}
function setName($newName){
$this->name = $newName;
}
function getName(){
return $this->name;
}
}
Start your classes from large letter (and use camelCase for variables and CamelCase for classes):
class Item
Do not use var $id inside of your class, use private or protected access modifiers:
private $id;
Access your class variables using $this:
function setId($id){
$this->id = $id;
}
Hope it will help
Not sure if this helps but I can't tell if you initialized the class at all.
<?php
class Item{ //Use Capital for class name
var $name = "test";
var $id = 3;
function setId($newID){
$this->id = $newID;
}
function getId(){
return $this->id;
}
function setName($newName){
$this->name = $newName;
}
function getName(){
return $this->name;
}
}
Then this is how you get name
$item = new Item(); //initialize
$item->getName(); //get name

PHP Classes load() method good/bad practice?

Just wondering if you could shed some light on best practices?
Would having a load method in a Class be the correct/best way?
Class Test extends Foo{
public $id;
public $name;
public function __construct()
{
parent::__construct();
}
public function load($id, $name)
{
$this->id = $id;
$this->name = $name;
}
}
Or would it be concidered better practice to just have the load method logic in the constructor?
Class Test extends Foo{
public $id;
public $name;
public function __construct($id, $name)
{
parent::__construct();
$this->id = $id;
$this->name = $name;
}
}
The 2nd option seems to be more logical to me as it's one less method and it's called automatically etc, however, I've seen the 1st option more often. Is there a reason for this? Any help would be appreciated!
The second option is best. A constructor is meant to prepare the object for use. It is the perfect place to initialize properties etc. Unless you have a good reason for using load() instead of the constructor, go with the second example.
The first option uses slightly more abstraction, I suppose.
I can see a situation where you might need to copy the code and separating the variable assignments into a load() or init() function might make your code a litter easier to update for the new purpose.
An advantage of the 1st option is that you don't require the developer to supply the information straight away. Although it is more error prone since one might forget about calling the load function. If all other functions require $id and $name to be set it's best to require the arguments when creating a new object.
On the other hand not having the load function prevents you from reloading the object with new values later on in the code.
You can combine the two by calling the load function from the constructor:
Class Test extends Foo{
public $id;
public $name;
public function __construct( $id, $name )
{
parent::__construct();
$this->load( $id, $name );
}
public function load($id, $name)
{
$this->id = $id;
$this->name = $name;
}
}
OR if you don't require the values to be set on creation you can use PHPs funky function overloading stuff:
Class Test extends Foo{
public $id;
public $name;
public function __construct()
{
parent::__construct();
if( func_num_args() === 2 ){
call_user_func_array(array($this, 'load'), func_get_args() );
}
}
public function load($id, $name)
{
$this->id = $id;
$this->name = $name;
}
}
You could extend load() per particular member.
Making each property protected or private and providing a set/get function for one of them.
That's an acceptable way and sometimes is better than overloading your constructor with dependencies and logic.
Try this and see if it helps you:
Class Test extends Foo{
protected $id;
protected $name;
public function __construct()
{
parent::__construct();
}
public function setId($id) {
$this->id = $id;
}
public function setName($name) {
$this->name = $name;
}
public function getId() {
return $this->id;
}
public function getName() {
return $this->name;
}
}
It's called getters and setters and it's a more clean and robust approach.
Besides, as mentioned in other answers - It provides better re-usability, ability to have your object clean of data with null values, but that's all dependent on what is the intent of your class!

How to override a static property of a parent object and let the parent object access the new value in PHP?

This is what I have: All objects that can be persisted on the database extend the DatabaseObject abstract class, which has all the logic code to actually watch for attribute changes and run the databas queries.
I'm using two static variables to define object-specific details. I define them generically in the base class, and then supposedly I overwrite them in the actual database objects.
The problem is: When the code in the parent class is actually executed, it uses the old parent value instead of the current object value.
Here's the code for the base class:
abstract class DatabaseObject {
public $id;
private static $databaseTable = NULL;
private static $databaseFields = array();
private $data = array();
private $changedFields = array();
public function IDatabaseObject($id) {
$this->id = $id;
$this->data = Database::GetSingle(self::$databaseTable, $id);
Utils::copyToObject($this, $this->data, self::$databaseFields);
}
public static function Load($id) {
return new self($userID);
}
public static function Create($data) {
$id = Database::Insert(self::$databaseTable, $data);
return new self($id);
}
public function Save() {
$data = Utils::copyFromObject($this, $this->changedFields);
Database::Update(self::$databaseTable, $data, $this->id);
}
public function __constructor() {
// We do this to allow __get and __set to be called on public vars
foreach(self::$databaseFields as $field) {
unset($this->$field);
}
}
public function __get($variableName) {
return $this->$variableName;
}
public function __set($variableName, $variableValue) {
// We only want to update what has been changed
if(!in_array($variableName, $this->changedFields) && in_array($variableName, self::$databaseFields)) {
array_push($this->changedFields, $variableName);
}
$this->$variableName = $variableValue;
}
}
And here's the code for one of the objects extending the base class above:
class Client extends DatabaseObject {
public static $databaseTable = "clients";
public static $databaseFields = array("name","contactName","primaryUserID","email","is_active","rg","cpf","cnpj","ie","addrType","addrName","addrNumber","addrComplement","addrPostalCode","addrNeighborhood","addrCity","addrState","addrCountry","phoneLandline","phoneFax","phoneMobile");
public $name;
public $contactName;
public $primaryUserID;
public $email;
public $is_active;
public $rg;
public $cpf;
public $cnpj;
public $ie;
public $addrType;
public $addrName;
public $addrNumber;
public $addrComplement;
public $addrPostalCode;
public $addrNeighborhood;
public $addrCity;
public $addrState;
public $addrCountry;
public $phoneLandline;
public $phoneFax;
public $phoneMobile;
public static function Load($id) {
return new Client($id);
}
}
What am I doing wrong here? Is there another way I can achieve the same result?
A brief addendum: I declare the attributes in the class body mainly to let it be seen by the NetBeans' auto-complete feature.
You are looking for Late Static Binding.
So you need to use:
static::$databaseTable
instead of
self::$databaseTable
This feature is available as of PHP 5.3. Simulating this in PHP 5.2 is very hard, because of two reasons: get_called_class is available only since PHP 5.3, too. Therefore it must be simulated, too, using debug_backtrace. The second problem is, that if you have the called class, you still may not use $calledClass::$property because this is a PHP 5.3 feature, too. Here you need to use eval or Reflection. So I do hope that you have PHP 5.3 ;)

Categories