What is the scope of constructor injected variables? - php

Is there a difference between this
$dependency1 = array();
$dependency2 = new SomeObject;
$di = new OtherObject($dependency1, $dependency2);
and this?
$di = new OtherObject(array(), new SomeObject);
In the first example, the $dependency vars are being exposed to the global scope, this is obvious. But what about the second example? Does it create encapsulation?
Is the same true for arguments passed into public methods as well?
I would test it, but I'm not sure how to go about it...

In second case, you won't be seeing those two parameters, unless you know, that OtherObject's constructor assigns them to some public properties.

The first method leaves two references to the parameters in global space. That's about it. Use the first method if there are additional components the need to be injected with the same shared dependencies.

Related

Why pass variables to a class instead of method

I was wondering what is the benefit of passing parameters to a class rather than to a method.
In terms of code, what's the benefit of doing this:
$books = new Books($book_id, $book_name);
instead of
$books = new Books;
$books->setBook($book_id, $book_name);
Thanks!
"Passing to a class" is not a thing. new Foo($bar, $baz) is instantiating a new object and is passing parameters to the constructor method:
class Foo {
public function __construct($bar, $baz) {
...
}
}
There's no difference as such between passing parameters to a regular method and to the constructor. The only difference is that the constructor is called when an object is instantiated, and other methods are called anytime later.
You should pass parameters to the constructor which the object requires at construction time. Typically this means you pass parameters which are required for the object to work at all. The constructor can throw an exception if it doesn't like the parameters, which means the object will fail to instantiate at all. This guarantees that the object is in a known, consistent state. Compare:
$api = new FooAPI($id, $password);
$api->doSomething();
$api = new FooAPI;
// $api->setId($id);
// $api->setPassword($password);
$api->doSomething(); // Error! No id and password given
While #deceze answer covers the major facts, I'd like to additionally state one of the most crucial point - perhaps emphasizing
paraphrasing from here
Each concrete object would have a constructor with a signature which
represents how a consumer should fully instantiate the object.
if you will see the assembly code of same code snippet which u have giv en you ll notice it increases around 5-6 instruction so it depends if you which method u want to prefer.but generally the first one is prefered if you know the values for instance variables while creating the object else the second one is prefered as it saves load of 5-6 instructions on processor.i have written the both code snippets in c++ and analysed their assembly code.

PHP OOP :: holding config 'global' values accessible to all classes

I am using a Factory class to manage the instantiation of objects and am passing into their constructors any dependency objects (Dependency Injection) e.g.
function createBasket() {
//pass in dependent objects
$apiCon = $this->createAPIConnector($this);
$basket = new Basket($this, $apiCon);
return $basket;
}
I am trying to avoid using the 'new' keyword within any classes (other than Factory), to allow simpler and more robust unit test, clearer code etc.
Now, my question relates to configuration values that many classes require e.g.
$apiURL = 'http://some.api.com';
$apiKey = 'abcde12345';
$adminEmail = 'someone#site.com';
These values remain constant for each application instance. I currently have them in a singleton class Config and they are reachable from within any class by the following:
$cfg = Config::getInstance();
$address = $cfg->apiURL;
However, this class instance is still a dependency within any Class that calls it, so should I think about passing this into class constructors, e.g.
function createBasket() {
//pass in dependent objects
$apiCon = $this->createAPIConnector($this);
$cfg = Config::getInstance();
//pass singleton config object to constructor
$basket = new Basket($this, $apiCon, $cfg);
return $basket;
}
...or perhaps pass them in via a set method, rather than via constructor:
function createBasket() {
//pass in dependent objects
$apiCon = $this->createAPIConnector($this);
$basket = new Basket($this, $apiCon);
//pass singleton config object to setter
$basket.setConfig(Config::getInstance());
return $basket;
}
Any guidance on the best approach would be much appreciated.
Thanks, James
Seems like that defeats the purpose of having a singleton config object that's globally available. The entire point is to avoid having to pass it as a parameter to every class you make.
Ive always seen them made as constants. I don't know that this is the "best" solution but I've seen this, and used it many times. Because its a const (the same is true for static vars, I would be interested to hear why one is better than the other) you don't need to instantiate the class which would probably save you some overhead if you want to be nit picky...
class SomeClass
{
const MYCONS = "APIKEY or Whateva";
}
then in when you need to use it require the file and do something like
SomeClass::MYCONST //to get your config info
I use a similar method, setting everything up in a single array or file and defining it accordingly:
$config = array(
'MYCONST_1'=>'myValue',
'USER'=>'username',
'PASSWORD'=>'y3ahr1ght'
);
foreach($config as $const=>$value){
define($const,$value);
}

PHP constructor uses? [duplicate]

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).

Sharing objects between PHP classes

What is the best way to share objects between other classes?
For example; a "database" object with functions that are required by the "article" and "user" objects.
I don't want to use globals (that includes singletons) or create a new instance of the object in each class, such as
function __construct() {
$this->database = new database;
$this->cache = new cache;
}
Would passing the objects in, eg.
class test{
function __construct( $obj ) {
$this->obj = $obj;
}
}
$database = new database;
$test = new test( $database );
Be the way to go?
Yes. Passing the objects to the constructor - or to a setter - is the best way to go. This pattern is known as dependency injection. It has the added benefit that it makes your code easier to test (using stubs or mocks).
Yes, that's pretty much the way you want to do. If a class has external requirements, don't create them inside the class, but require them as arguments in the constructor.
The way to go would be singletons if they have a single instance. If not, the only way is to pass them during initialization (say: in the constructor).
That would be a step in the right direction, but it does seem to me that you do actually want a singleton there, even if not actually constrained in code.
You could also use objects that have been loaded in session or in cache (APC,memcached) before.
Personnaly i think singleton is the best way to go there (especially for database class)

Benefits of using a constructor?

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).

Categories