Multiple time execution bypass - php

I have the follow (sample) code:
class Foo {
public function __construct() {
$this->bar = new Bar();
$this->baz = new Bazr();
}
}
class Bar extends Foo {
public function __construct() {
parent::__construct();
$baz = $this->baz->alert();
}
}
class Baz extends Foo {
public function __construct() {
parent::__construct();
}
public function alert() {
echo('Hello!');
}
}
new Foo();
Which will generate an Fatal error: Maximum function nesting level of '100' reached, aborting!. What I want is, exactly this, ofcourse with different code and no errors.
What I want is one way to know when my instance is already created and not allow more instances of same object, avoiding circular reference.
Learned about Singletom, but, nothing worked. Have any idea?

The constructor of Foo calls the constructor of Bar which calls the constructor of Foo which calls the constructor of Bar... you get the idea. After 100 times it tells you it's dizzy. Don't create a circular reference like that.

I do not quite understand why you need all this? If only because to get methods of Bar/Baz in class Foo, then you can use:
class Foo {
public function __construct() {
Bar::init();
}
}
class Bar extends Foo {
public function __construct() {
parent::__construct();
}
public function init() {
Baz::alert();
}
}
class Baz extends Foo {
public function __construct() {
parent::__construct();
}
public function alert() {
echo 'Hello!';
}
}
new Foo();

Implement dependence Injection is the solution:
class Foo {
public function __construct() {
$this->bar = new Bar(new Baz());
}
}
class Bar {
public function __construct($baz = null) {
$this->baz = $baz;
$this->baz->alert();
}
}
class Baz {
public function __construct() {
}
public function alert() {
echo('Hello!');
}
}
new Foo();

Related

PHP Prophecy Stub method not called

I can't get this obvious test to pass.
Foo gets a Bar in its constructor and when calling Foo::m(), Bar::bar() gets called.
use PHPUnit\Framework\TestCase;
class Bar {
public function bar() {
echo "BAR";
}
}
class Foo {
protected $bar;
public function __construct($bar) {
$this->bar= $bar;
}
public function m() {
$this->bar->bar();
}
}
class FooTest extends TestCase {
public function testM() {
$bar = $this->prophesize(Bar::class);
$bar->bar()->shouldBeCalled();
$foo = new Foo($bar);
$foo->m();
}
}
Prophecy fails to register the call to Bar::bar() somehow...
Some predictions failed:
Double\Bar\P1:
No calls have been made that match:
Double\Bar\P1->bar()
but expected at least one.
Your $bar variable contains an instance of ObjectProphecy, which is unrelated to the Bar class. Call $bar->reveal() to get a test double which is an extension of Bar:
public function testM()
{
$bar = $this->prophesize(Bar::class);
$bar->bar()->shouldBeCalled();
$foo = new Foo($bar->reveal());
$foo->m();
}

Can't call function of another class using OOP

I'm a bit rusty with php, I want to know how I can call the function login available in class2, inside class1. This is the example:
<?php
require_once("property2.php");
class Class1
{
public function __construct()
{
$cls2 = new Class2()
}
public function method1()
{
$cls2->login() //cl2 is undefined
}
} ..
//this is the function
...
class Class2
{
public function __construct()
{
}
//This is the function to call
public function login()
{
//Some stuff
}
} ...
Now PHPSTORM say that the variable cls2 is undefined. What I did wrong?
When you are setting your variable youre not setting it as a class property. Define a private variable inside your class, and "set it and get it" using the $this keyword.
class Class1 {
private $cls2;
public function __construct() {
$this->cls2 = new Class2();
}
public function method1() {
$this->cls2->login();
}
}
Another way to achieve this is to use Inheritance, where one class is considered a "parent" class. You would achieve this by using extends
class Class1 {
public function __construct() {
//Some stuff
}
public function login() {
//Some stuff
}
}
class Class2 extends Class1 {
public function __construct() {
parent::__construct();
}
public function method1() {
$this->login();
}
}
class Class1
{
public function __construct()
{
$cls2 = new Class2();
}
public function method1()
{
$cls2->login() //cl2 is undefined
}
}
When you create Class1 and call $cls2 = new Class2();, $cls2 exists only locally. You have to make it a class property:
class Class1
{
public $cls2;
public function __construct()
{
$this->cls2 = new Class2();
}
public function method1()
{
$this->cls2->login();
}
}
And then you'll be able to access it using $this keyword.
Also please watch for semicolons.

PHP class property reference to an object

class Hello {
public function hi() {
echo "Hello, hi!\n";
}
}
class ParentClass {
public $obj;
public function __construct() {
$this->obj = new Hello;
}
}
class Test extends ParentClass {
public function __construct() {
$this->obj->hi();
}
}
$temp = new Test;
The error message I get is "Call to a member function hi() on a non-object". $obj should be referencing to an instance of the class "Hello", but it obviously is not - what am I doing wrong?
You are defining __construct() in your Test class but not calling the parent constructor. If you want the parent constructor to execute, you need to explicitly specify so. Add a call to ParentClass constructor in in Test class constructor.
class Test extends ParentClass {
public function __construct() {
parent::__construct();
$this->obj->hi();
}
}
Also as #Tasos Bitsios pointed in his comment you also need to update your ParentClass constructor as follows:
class ParentClass {
public $obj;
public function __construct() {
$this->obj = new Hello; // Use $this->obj and not just $obj.
}
}
You need call to parent constructor:
class Test extends ParentClass {
public function __construct() {
parent::__construct();
$this->obj->hi();
}
}

Using a class that has params inside another class (PHP)

I am trying to access the results of a function that is public inside another class, but I'm not entirely sure how to do this. The class i'm trying to access require parameters, so the class_name::function() method is not working. I'm still new to working with classes, and trying to learn it.
Class one:
class foo {
private $var1;
function __construct($param) {
$this->var1 = $param
}
public function myFunc() {
echo $this->var1;
}
}
Class 2
class bar {
public function secondFunc() {
var_dump(**RESULT FROM foo->myFunc HERE);
}
}
These two classes are a basic example of what i'm actually doing, but from this you should get the general idea of my question.
For the correct result to display, the first class needs the params passed to it otherwise the function fails.
I tried using foo::bar(), but this doesn't pass any params to the first class, and it therefor fails.
So, how do I access myFunc from foo inside secondFunc from bar?
You have to pass an instance of foo to bar:
class Foo {
private $var1;
function __construct($param) {
$this->var1 = $param
}
public function myFunc() {
return $this->var1;
}
}
class Bar {
private $foo;
function __construct(Foo $foo) {
$this->foo = $foo
}
public function secondFunc() {
var_dump($this->foo->myFunc());
}
}
$bar = new Bar(new Foo('something'));
$bar->secondFunc();
Is that what you want?
Your example isn't very practical but here is the basic idea
public function secondFunc($dependency) {
var_dump($dependency->myFunc());
}
or...
public function secondfunc() {
$foo = new foo();
var_dump($foo->myFunc();
}
What about
class bar {
public function secondFunc() {
$foo = new foo($param);
var_dump($foo->myFunc());
}
}
Or do you need something in one line?

php extending but with a new constructor...possible?

I have a class:
class test {
function __construct() {
print 'hello';
}
function func_one() {
print 'world';
}
}
what I would like to do is a have a class that sort of extends the test class. I say 'sort of', because the class needs to be able to run whatever function the test class is able to run, but NOT run the construct unless I ask it to. I do not want to override the construct. Anyone has any idea how to achieve this?
class test {
function __construct() {
print 'hello';
}
function func_one() {
print 'world';
}
}
class test_2 extends test {
function __construct() {
if (i want to) {
parent::__construct();
}
}
}
What's wrong with overriding the construct?
class foo extends test {
function __construct() { }
}
$bar = new foo(); // Nothing
$bar->func_one(); // prints 'world'
You could define a "preConstructor" method in your sub-classes that your root-class constructor would execute, and use a boolean flag to determine whether constructor code should be executed.
Like so:
class test
{
protected $executeConstructor;
public function __construct()
{
$this->executeConstructor = true;
if (method_exists($this, "preConstruct"))
{
$this->preConstruct();
}
if ($this->executeConstructor == true)
{
// regular constructor code
}
}
}
public function subTest extends test
{
public function preConstruct()
{
$this->executeConstructor = false;
}
}

Categories