Here's some code to clarify the question.
Application.php:
class Application {
var $class1;
var $class2;
function __construct() {
include_once('Class1.php');
include_once('Class2.php');
$this->class1 = new Class1($this);
echo $this->class1->testvar; // echoes 1
$this->class2 = new Class2($this);
echo $this->class1->testvar; // echoes 2
}
}
Class1.php:
class Class1 {
var $app;
var $testvar = 1;
function __construct($app) {
$this->app = $app;
}
}
Class2.php:
class Class2 {
var $app;
function __construct($app) {
$this->app = $app;
$this->app->class1->testvar = 2;
}
}
What's wrong with this approach?
I noticed in some cases a recursion occurs and the consistency is not hmmm "consistent"...
Any help on the issue is appreciated.
Mainly I need to be able to access Class1 variables from Class2, extends didn't work well for these purposes.
This:
$this->app->class1->testvar = 2;
is breaking the Law of Demeter:
The Law of Demeter (LoD) or principle of least knowledge is a design
guideline for developing software, particularly object-oriented
programs. In its general form, the LoD is a specific case of loose
coupling. The guideline was proposed at Northeastern University
towards the end of 1987, and can be succinctly summarized in one of
the following ways:
Each unit should have only limited knowledge about other units: only
units "closely" related to the current unit.
Each unit should only talk to its friends; don't talk to strangers.
Only talk to your immediate friends.
The fundamental notion is that a given object
should assume as little as possible about the structure or properties
of anything else (including its subcomponents), in accordance with the
principle of "information hiding".
Your Class2 is making a lot of assumptions about what Application looks like, making the design of Application inflexible because Class2 depends on it. You should only inject the immediately required dependencies into a class to preserve flexibility. Class2 would look a lot better like this:
class Class2 {
protected $class1;
public function __construct(Class1 $class1) {
$this->class1 = $class1;
$this->class1->setTestVar(2);
}
}
Make properties protected to encapsulate them.
If you require Class1, type hint for Class1 and require Class1, not some intermediate object which you don't really need.
Use setter methods like setTestVar instead of setting public properties. Again: encapsulation. You also preserve the flexibility to change your internal implementation of Class1 around, as long as the method setTestVar stays as it is. Think about using a defined interface between objects, not just mess around with other object's properties.
just extend the class1 to access it's method and variable, and since class1 extends the class class2 you will also be able to access the method and variable it contains
You can try this,
application.php
include_once('class1.php');
include_once('class2.php');
class application extends class1{
function hello(){
// variable from class1
echo $this->class1var."<BR>";
// variable from class2
echo $this->class2var."<BR>";
}
}
class1.php
class class1 extends class2{
public $class1var = 'hello';
}
class2.php
class class2 {
public $class2var = 'world';
}
calling the method hello
$app = new application();
$app->hello();
result:
hello
world
Related
First file:
class Class_one {
public function __construct() {
}
public function show_name() {
echo "My Name is Siam";
}
public function show_class() {
echo "I read in class 7";
}
}
Second file:
<?php
require_once './Class_one.php';
class Class_two {
public $class_one;
public function __construct() {
$aa = new Class_one();
$this->class_one = $aa;
}
public function history() {
$this->class_one->show_name();
}
}
$ab = new Class_two();
$ab->history();
What will happen if i don't instantiate class_one in class_two and extend class_one into class_two? Is there any difference?
There's only one potential gotcha here: Class_two won't have direct access to Class_one private/protected methods and variables. That can be a good thing (encapsulation is where a class does some specific task and you don't want children to interfere with it), but it can also mean you can't get to the data you need.
I would suggest you do Class_two as a dependency injection (as shown in your example), however
class Class_two {
public $class_one;
public function __construct(Class_one $class) {
$this->class_one = $class;
}
}
It should be a semantic difference:
You use inheritance when relationship between two classes can be expressed with to be verb. For example: My Ford is a Car
You use association/composition when relationship between two classes can be expressed with to have verb. For example: My car has an engine.
Above rules should be the first consideration when choosing inheritance or association in object-oriented programming. There've been always discussion about avoiding inheritance, and some will argue that you should choose composition over inheritance. See this other Q&A: Prefer composition over inheritance?
In terms of pure coding, as #Machavity on his answer has already said, there could be accessibility limitations when using composition instead of inheritance, but I wouldn't decide which approach to use based on member accessibility.
So I am a laravel developer and even though I have worked with it for a while now, and I love how the magic happens beneath the surface, how it automatically binds implementations when instantiating classes via the IoC container, right now I am trying to go to the basics of design patters and learn how things actually work.
So I started with the Animal example:
abstract class Animal
{
abstract function makeSound();
}
class Dog extends Animal
{
public function makeSound()
{
echo "Bark!\n";
}
}
class Cat extends Animal
{
public function makeSound()
{
echo "Bark!\n";
}
}
So I am reading Head First Design Patterns and I am trying to make the most of the book. At this point every time I create a new Animal, I will have to implement the make sound method which will differ in most cases.
So the book tells me that I should code a Soundable interface and then have implementations of that interface in the Animal extended classes.
I finally came up with something like this:
interface Soundable
{
function sound();
}
class Bark implements Soundable
{
public function sound()
{
return "Bark!\n";
}
}
class Meow implements Soundable
{
public function sound()
{
return "Meow!\n";
}
}
class Animal
{
public $soundable;
public function __construct(Soundable $soundable)
{
$this->soundable = $soundable;
}
public function makeSound()
{
echo $this->soundable->sound();
}
}
class Dog extends Animal
{
}
class Cat extends Animal
{
}
function makeAnimal(Animal $animal){
return $animal;
}
// Making a dog
$animal = makeAnimal(new Dog(new Bark()));
$animal->makeSound();
// Making a cat
$animal = makeAnimal(new Cat(new Meow()));
$animal->makeSound();
So now when I have another animal that barks or meows, I can simple instantiate that implementation while making an animal.
Now my question is how do I tell PHP to automatically pass the new Bark() while instantiating the Dog class since it will bark and I don't want to write it every time I instantiate a new Dog object.
So how do I use a similar magic that Laravel uses to pass the Bark object automatically while instantiating Dog.
PS: I am still learning so I might be going in the wrong direction altogether while understanding these principles. Please guide me if you know better.
First of all, a small note: the book is wrong. The interface should be called Audible or Vocal. "Soundable" is not a real word an the author should be embarrassed. Also, calling a variable in the same name as an interface is kinda bad.
Another thing is: the Laravel's IoC is actually just a glorified service locator, so it wouldn't really help you here.
Usually, you would have two options:
use a factory (which in this particular case would painful and/or tricky)
use a dependency injection container - preferably a reflection-base one
I tend to recommend Auryn in these case. Though, if you are willing to jump few additional hoops and suffer through limited configuration, you can also use Symfony's DIC.
If you were using Auryn, initialization of your dog and cat would be just:
$injector = new Auryn\Injector;
$dog = $injector->make('Dog');
$cat = $injector->make('Cat');
The library would on its own look up the reflection of the constructor for Dog and detect that it will also need to create a new Bark instance.
You can create simply animal factory (sounds strange) with factory methods.
Factories
Factory classes are often implemented because they allow the project to follow the SOLID principles more closely. In particular, the interface segregation and dependency inversion principles.
For more information look here https://www.sitepoint.com/understanding-the-factory-method-design-pattern/
Just remember if you want to write down some unit test don't use static methods, just instantiate factory, there may be need in future to create factory with some dependencies.
<?php
class AnimalFactory
{
public function createDog() : Dog
{
return new Dog(new Bark());
}
}
$factory = new AnimalFactory();
$dog = $factory->createDog();
I think using IoC here would be good solution.
From Laravel Docs (Contextual binding)
Sometimes you may have two classes that utilize the same interface, but you wish to inject different implementations into each class. For example, when our system receives a new Order, we may want to send an event via PubNub rather than Pusher. Laravel provides a simple, fluent interface for defining this behavior:
$this->app->when('App\Handlers\Commands\CreateOrderHandler')
->needs('App\Contracts\EventPusher')
->give('App\Services\PubNubEventPusher');
So your service provider in laravel could look like
public function register()
{
$this->app->when(Dog::class)->needs(Soundable::class)->give(Bark::class);
$this->app->when(Cat::class)->needs(Soundable::class)->give(Meow::class);
}
And then you could instantiate your class using Laravel's dependency injection containter
$dog = app()->make(Dog::class);
$dog->sound(); // Bark!
$cat = app()->make(Cat::class);
$cat->sound(); // Meow!
So summing it up, and relating to your question:
So how do I use a similar magic that Laravel uses to pass the Bark
object automatically while instantiating Dog.
Dependency Injection Container will suit your needs
I don't know laravel, but in my opinion your code should have been:
interface Soundable
{
function sound();
}
class Animal
{
protected name;
public function __construct($name) {
$this->name=name;
}
public function get_name() { return $this->name; }
}
class Dog extends Animal implements Soundable
{
public function sound()
{
return "Bark!\n";
}
}
class Cat extends Animal implements Soundable
{
public function sound()
{
return "Meow!\n";
}
}
// Making a dog
$animal = new Dog("Fido");
$animal->sound();
// Making a cat
$animal = new Cat("Fuffi");
$animal->sound();
echo $animal->get_name(); // print "Fuffi"
So, you can see that if you want only to implement the interface, you don't even need the Animal class. In fact, I have mantained it only to shot that it can still be useful in order to implement some method that can be useful to all descending classes (for example, get_name, that return the protected attribute "name").
Can we create an object of a class inside another class in php?I hav made a small application in php,now I am trying to convert the entire code in a class-methods-object fashion.I m now Confused.
You you can do that, but whether you should depends on the lifetime of the two classes and their relation to each other. Basically, you have the choice between Composition and Aggregation.
Composition
You use Composition when the created object has a lifetime equal or less than the object that will use it, e.g.
class A
{
private $belongsToAOnly;
public function __construct()
{
$this->belongsToAOnly = new IBelongToA;
}
}
In this case A "owns" IBelongToA. When A is destroyed, IBelongToA is destroyed too. It cannot live on it's own and is likely just an implementation detail of A. It could be a ValueObject like Money or some other Data Type.
From Craig Larman's "Applying UML and Patterns":
the composite is responsible for creation and deletion of it's parts - either by itself creating/deleting the parts, or by collaborating with other objects. Related to this constraint is that if the composite is destroyed, its parts must be destroyed, or attached to another composite"
Aggregation
You use Aggregation when the lifetime of the created object is longer:
class A
{
private $dbAdapter;
public function __construct(DbAdapter $dbAdapter)
{
$this->dbAdapter = $dbAdapter;
}
}
Unlike with Composition, there is no implication of ownership here. A uses DbAdapter but when A is destroyed DBAdapter lives on. It's a "uses" relationship instead of an "owns" relationship.
Creator Pattern (GRASP)
A good heuristic to decide when an object may create another object at runtime can be found in the Creator Pattern in GRASP which states that objects may create other objects when
Instances of B contains or compositely aggregates instances of A
Instances of B record instances of A
Instances of B closely use instances of A
Instances of B have the initializing information for instances of A and pass it on creation.
Alternatively, you can create Factories whenever you need to create instances of something and aggregate the factory instances, which will give you a cleaner separation of collaborators and creators.
Testability
An issue stemming from creating objects within objects is that they are difficult to test. When you do unit-testing, you usually do not want to recreate and bootstrap the entire system environment but concentrate on testing just that particular class in isolation. To do that, you swap out dependencies of that class with Mock Objects. You cannot do that when you use Composition.
So depending on what the collaborators of a class do, you might want to decide to always use Aggregation, because then you are effectively doing Dependency Injection all the way, which will allow you to swap out collaborators of a class easily, for instance to replace them with Mocks.
Yes you can, but that increases code coupling and makes testing harder.
I'd suggest creating it outside the class and pass it as an argument (it is called Dependency Injection).
class Foo
{
}
class Bar
{
public function __construct(Foo $foo)
{
$this->foo = $foo;
}
}
$foo = new Foo();
$bar = new Bar($foo);
yes you can do it ..
here is one example..
a.php
<?php
class a{
public function function_1(){
echo "b";
}
}
?>
b.php
<?php
include_once ("a.php");
class b{
public function function_b(){
$a = new a;
$a->function_1();
}
}
$b= new b;
$b->function_b();
?>
Yes, you can create an object from a specific class from inside another class.
class SomeClass{
}
class SomeOtherClass {
function hello(){
$o = new SomeClass;
}
}
Yes, you can also define a function in a class. You can do everything in a class in php, please post your code where you confused.
Examples:
Object in a class.
class Foo
{
public $bar; // another object!
public __construct()
{
$this->bar = new Bar();
}
}
(global)Function in a class
<?php
class Foo
{
public function __construct()
{
function __construct()
{
echo "Yes, I'm a global function!";
}
}
}
new Foo();
__construct();
?>
Why would you use such abstract? Does it speed up work or what exactly its for?
// file1.php
abstract class Search_Adapter_Abstract {
private $ch = null;
abstract private function __construct()
{
}
abstract public funciton __destruct() {
curl_close($this->ch);
}
abstract public function search($searchString,$offset,$count);
}
// file2.php
include("file1.php");
class abc extends Search_Adapter_Abstract
{
// Will the curl_close now automatically be closed?
}
What is the reason of extending abstract here? Makes me confused. What can i get from it now?
You can use abstract classes to define and partially implement common tasks that an extended class should do. Since explaining it is difficult without an example, consider this:
Without abstract classes, you would have to define two basic classes with the same methods and implementation. Since OOP is all about preventing code duplication, this is quite wrong:
class Car {
public $brand = 'mercedes';
public function gasPerMile($weight)
{
// Useless calculation, purely for illustrating
$foo = $weight * 89 / 100;
return $foo;
}
public function carSpecificFunction()
{
// Only present in class Car
}
}
class Truck {
public $brand = 'MAN';
public function gasPerMile($weight)
{
// Useless calculation, purely for illustrating
$foo = $weight * 89 / 100;
return $foo;
}
public function truckSpecificFunction()
{
// Only present in class Truck
}
}
Now you have some common properties and methods, which are duplicated in two classes. To prevent that, we could define an abstract class from which Car and Truck are extended. This way, common functionalities are kept in one place and the extended classes will implement specific properties and methods for either the Truck or the Car.
abstract class Vehicle {
abstract public $brand;
public function gasPerMile($weight)
{
// Useless calculation, purely for illustrating
$foo = $weight * 89 / 100;
return $foo;
}
}
This way, you ensure that atleast every class that extends Vehicle has to have a brand specified and the common gasPerMile() method can be used by all extended classes.
Of course, this is a simple example, but hopefully it illustrates why abstract classes can be useful.
So you can implement different Search adapters and all of them must implement that search method. See inheritance here.
Basically what you get is that every class extending "Search_Adapter_Abstract" can be used as a Search Adapter. The behaviour changes (because the method search is implementend differently) but you guarantee the "search" method is there with that signature.
This isn't going to be a popular answer, but still...
abstract, interface, private and other keywords, borrowed from Java, are elements of cargo cult programming and serve no real purpose in PHP, except to make the author appear more "serious" and "professional".
Explanation: these keywords are compile-time contracts, that have no effect on how your program runs and only meant as an aid for a compiler... assuming you have one. In a compiled language, like Java or C#, you physically cannot deploy a program that violates a contract, e.g. doesn't implement an abstract method. You simply don't get it compiled. This is a Good Thing, because you can fix some kinds of bugs very quickly, without testing and debugging.
PHP, on the contrary, doesn't have a compiler, and performs all contract checks at run time. This is a Bad Thing, because you need to test and debug to find contract violations manually. Consider the following:
class Abs {
abstract function implementMe();
}
if ($_GET['x'] == 'foo')
include "GoodClass.php";
if ($_GET['x'] == 'bar')
include "BadClass.php";
where "BadClass" extends "Abs", but doesn't implement "implementMe" method. This script can be deployed and will run just fine until someone calls it with "?x=bar" and then - bang! - your program suddenly crashes. To make the things worse, this will be a "fatal" error, so that you won't be even able to handle it in a reasonable way.
That is, abstract and friends are not only useless, but also quite harmful in PHP. Not only they don't help you with bug hunting, but also they are potential source of even more glitches. Stay away.
Wondering if this is possible in PHP Land:
Let's say I have a class as follows:
class myClass{
var $myVar;
...
myMethod(){
$this->myVar = 10;
}
}
and another class:
class anotherClass {
...
addFive(){
$this->myVar += 5;
}
}
The 'anotherClass' is 3500 lines long and I just want the single 'addFive' method to use in myClass.
Is there a way I can import the function and be able to call it in my class and the $this would reference the myClass object?
Is this good/bad practice?
(optional) How does this work in Python? (Just curious as I'm starting to learn Python)
The easiest way to do this is have one class extend the other
class myClass extends anotherClass {
}
The myClass class now has access to all the methods of anotherClass that are public or protected.
If you only want the class to have one method of the other, or it's not practical to have one class extends from the other, there's nothing built into PHP that will allow you to do this. The concept you're looking to Google for is "Mixin", as in Mix In one class's functionality with another. There's an article or two on some patterns you could try to achieve this functionality in PHP, but I've never tried it myself.
Good idea/Bad Idea? Once you have the technique down it's convenient and useful, but costs you in performance and makes it harder for a newcomer to grok what you're doing with your code, especially (but not limited to) someone less familiar with OO concepts.
A better approach would be to move the complex method into its own class. Then both of your classes can instantiate it, pass any necessary data, and call the method.
If your myClass extends anotherClass it inherits all the methods and properties of anotherClass (except those marked private).
class AnotherClass {
protected $myVar;
public function addFive(){
$this->myVar += 5;
}
}
class MyClass extends AnotherClass {
public function __construct() {
$this->myVar = 0;
}
public function myMethod(){
$this->myVar = 10;
}
}
$m = new MyClass;
$m->myMethod();
$m->addFive();
var_dump($m);
prints
object(MyClass)#1 (1) {
["myVar":protected]=>
int(15)
}