I'm still learning OOP so this might not even be possible (although I would be surprised if so), I need some help calling another classes method.
For example in ClassA I have this method:
function getName()
{
return $this->name;
}
now from ClassB (different file, but in the same directory), I want to call ClassA's getName(), how do I do that? I tried to just do an include() but that does not work.
Thanks!
//file1.php
<?php
class ClassA
{
private $name = 'John';
function getName()
{
return $this->name;
}
}
?>
//file2.php
<?php
include ("file1.php");
class ClassB
{
function __construct()
{
}
function callA()
{
$classA = new ClassA();
$name = $classA->getName();
echo $name; //Prints John
}
}
$classb = new ClassB();
$classb->callA();
?>
If they are separate classes you can do something like the following:
class A
{
private $name;
public function __construct()
{
$this->name = 'Some Name';
}
public function getName()
{
return $this->name;
}
}
class B
{
private $a;
public function __construct(A $a)
{
$this->a = $a;
}
function getNameOfA()
{
return $this->a->getName();
}
}
$a = new A();
$b = new B($a);
$b->getNameOfA();
What I have done in this example is first create a new instance of the A class. And after that I have created a new instance of the B class to which I pass the instance of A into the constructor. Now B can access all the public members of the A class using $this->a.
Also note that I don't instantiate the A class inside the B class because that would mean I tighly couple the two classes. This makes it hard to:
unit test your B class
swap out the A class for another class
You would need to have an instance of ClassA within ClassB or have ClassB inherit ClassA
class ClassA {
public function getName() {
echo $this->name;
}
}
class ClassB extends ClassA {
public function getName() {
parent::getName();
}
}
Without inheritance or an instance method, you'd need ClassA to have a static method
class ClassA {
public static function getName() {
echo "Rawkode";
}
}
--- other file ---
echo ClassA::getName();
If you're just looking to call the method from an instance of the class:
class ClassA {
public function getName() {
echo "Rawkode";
}
}
--- other file ---
$a = new ClassA();
echo $a->getName();
Regardless of the solution you choose, require 'ClassA.php is needed.
File 1
class ClassA {
public $name = 'A';
public function getName(){
return $this->name;
}
}
File 2
include("file1.php");
class ClassB {
public $name = 'B';
public function getName(){
return $this->name;
}
public function callA(){
$a = new ClassA();
return $a->getName();
}
public static function callAStatic(){
$a = new ClassA();
return $a->getName();
}
}
$b = new ClassB();
echo $b->callA();
echo $b->getName();
echo ClassB::callAStatic();
Related
I have the next code
<?php
interface SimpleInterface
{
public function method(): self;
}
trait SimpleTrait
{
public function method(): self
{
return $this;
}
}
class SomeClass implements SimpleInterface
{
use SimpleTrait;
}
But PHP says that RenderableTrait->setLayout(layout:string) isn't compatible with RenderableInterface->setLayout(layout: string)
Obviously, because interface expects self as returned value, but in trait I return Trait itself and it's not compatible. Are there any solutions?
Change you return type self for SimpleInterface
https://3v4l.org/LTc8E
<?php
trait Test {
public function test() {
return $this;
}
}
class Foo {
use Test;
}
class Bar {
use Test;
}
$f = new Foo();
$b = new Bar();
// object(Foo)
var_dump($f->test());
// object(Bar)
var_dump($b->test());
//So for you case
interface SimpleInterface
{
public function method(): SimpleInterface;
}
trait SimpleTrait
{
// This method will work only in classes that implements SimpleInterface
public function method(): SimpleInterface
{
return $this;
}
}
class SomeClass implements SimpleInterface
{
// Traits $this is now SomeClass
use SimpleTrait;
}
$s = new SomeClass();
// object(SomeClass)
var_dump($s->method());
How can I stub a method of an object that is hardcoded in app? In rspec there is a method allow_any_instance_of.
I can't reverse the dependency, the initialisation of the object should still be hardcoded.
So, I have ClassA
namespace App
class ClassA
{
public function doSomething(){
// more code
return($sth);
}
}
It is used in ClassB
namespace App
class ClassB
{
protected $instanceOfA;
public function __construct(){
$this->instnaceOfA = new ClassA();
}
public function methodToTest(){
$result = $this->instanceOfA->doSomething()
// more code
}
}
I think this is what you're looking for? a plugable interface? if you change the classB to ClassA on line 33 it will switch to the other class.
Interface TheInterface
{
public function doSomething();
}
class ClassA implements TheInterface
{
public function doSomething(){
echo __METHOD__;
}
}
class ClassB implements TheInterface
{
public function doSomething(){
echo __METHOD__;
}
}
class ClassProcess
{
protected $instance;
public function __construct(TheInterface $class){
$this->instance = $class;
}
public function methodToTest(){
$this->instance->doSomething();
}
}
$process = new ClassProcess(new ClassB());
$process->methodToTest();
Say object of class B is attribute of class A. How can I call method of object of class A from method of object of class B? What would be nice solution without passing object link?
Thanks!
Here goes code sample:
class A{
var $b;
function __construct(){
$this->b = new B();
}
function f1(){
$this->b->f3();
}
function f2(){
echo 'hello!';
}
}
class B{
function f3(){
// call f2() method in object $obj(not new A())
}
}
$obj = new A();
$obj->f1();
You can use a static function
public static function f2{
echo 'hello!';
}
with f3 defined as
function f3(){
A::f2();
}
This may not ultimately be the solution you want, however. See more info here.
The only way you can access that instance's function is if you inject it on the B object as a dependency. You can inject it within the constructor, like this:
<?php
class A {
protected $b;
public function __construct() {
$this->b = new B($this);
}
public function f1() {
$this->b->f3();
}
public function f2() {
echo 'hello!';
}
}
class B {
protected $a;
public function __construct($a) {
$this->a = $a;
}
public function f3() {
$this->a->f2();
}
}
$obj = new A();
$obj->f1();
So say I have the following code,
$obj = new foo();
echo $obj;
class foo {
public function __construct()
{
return 'a';
}
}
How do I make $obj echo the string 'a'?
How do I make $obj refer to or equal what is returned by the object/class?
Need to return a value from a __construct(), and also a normal private function within another class. For example:
$obj2 = new foo2();
echo $obj2;
class foo2 {
public function __construct()
{
bar();
}
private bar()
{
return 'a';
}
}
Thanks!
you can use the magic __toString() method to convert your class to a representing string.
You should not return something in your constructor, __toString() is automaticly called if you try to use your instance as string (in case of echo).
from php.net:
<?php
// Declare a simple class
class TestClass
{
public $foo;
public function __construct($foo)
{
$this->foo = $foo;
}
public function __toString()
{
return $this->foo;
}
}
$class = new TestClass('Hello');
echo $class;
?>
http://www.php.net/manual/en/language.oop5.magic.php#object.tostring
Constructors in PHP are more like initialisation functions; their return value is not used, unlike JavaScript for instance.
If you want to change the way objects are normally echoed you need to provide the magic __toString() method:
class foo
{
private $value;
public function __construct()
{
$this->value = 'a';
}
public function __toString()
{
return $this->value;
}
}
A private method that would return the value can be used in a similar manner:
class foo2
{
private function bar()
{
return 'a';
}
public function __toString()
{
return $this->bar();
}
}
From php manual:
[...] Static method calls are resolved at compile time.
When using an explicit class name the method is already identified completely and no
inheritance rules apply. If the call is done by self then self is translated to
the current class, that is the class the code belongs to.
Here also no inheritance rules apply [...]
..so im looking for a way to emulate the standard oop inheritance with static singleton.
Code explain better:
// Normal inheritance: my goal.
class Foo{
public function test(){
echo "Foo->test()\n";
}
}
class Bar extends Foo{
public function other_test()
{
echo "Bar->other_test()\n";
}
}
$obj = new Bar();
echo get_class($obj) . "\n";
$obj->test();
$obj->other_test();
/*
Output:
Bar
Foo->test()
Bar->other_test()
*/
// How i would love to do:
class Foo2{
public static function test2()
{
echo "Foo2::test2()\n";
}
// Singleton?
public static $_instance;
public static function get_instance()
{
if(is_null(self::$_instance))
{
self::$_instance = new self();
}
return self::$_instance;
}
}
class Bar2 extends Foo2{
public static function other_test2()
{
echo "Bar2::other_test2()\n";
}
}
$obj2 = Bar2::get_instance();
echo get_class($obj2) . "\n";
$obj2::test2();
$obj2::other_test2();
/*
Output:
Foo2
Foo2::test2()
Fatal error: Call to undefined method Foo2::other_test2()
*/
echo "\n-------\n";
// How im doing actually:
interface Foo3{
public static function get_instance();
}
class Bar3 implements Foo3{
// Singleton?
public static $_instance;
public static function get_instance()
{
if(is_null(self::$_instance))
{
self::$_instance = new self();
}
return self::$_instance;
}
public static function test3()
{
echo "Bar3::test3()\n";
}
public static function other_test3()
{
echo "Bar3::other_test3()\n";
}
}
$obj3 = Bar3::get_instance();
echo get_class($obj3) . "\n";
$obj3::test3();
$obj3::other_test3();
/*
Output:
Bar3
Foo3::test3()
Bar3::other_test3()
*/
The last 'way' force me to avoid the get_instance and static variables to be placed in the parent class, so I do not consider it as a best solution.. if for some reason my get_instance() function will change in the future, i dont want to edit all classes (inheritance! inheritance! we all want inheritance!)
So, is there a way or a best practices to solve this problem?
p.s: php5.3.2
The Singleton pattern in PHP is something like this:
class Singleton {
private static $instance = null;
// Constructor is private, so class cannot be instantiazed from outside
private function __construct() {
}
public static function getInstance() {
if (static::$instance === null) {
static::$instance = new Singleton();
}
return static::$instance;
}
public static function test() {
echo 'Singleton::test()';
}
public function __sleep() {
throw new Exception('Serialization is not alowed.');
}
public function __wakeup() {
throw new Exception('Serialization is not alowed.');
}
public function __clone() {
throw new Exception('Cloning is not alowed.');
}
}
For you is important that keyword static, then this:
class B extends Singleton {
public static function test2() {
echo 'B::test2()';
}
}
$b = B::getInstance();
B::test();
B::test2();
// Singleton::test()
// B::test()
Is this you looking for?