I cant manage to call a static function (with a constant) from a extended class. Here is my code:
(1st file)
class A
{
function isXSet()
{
return X;
}
public static function setX()
{
define('X', 1);
}
}
(second file)
include('/*first file*/');
class B extends A
{
A::setX();
}
How can i manage to do that ?
Your code here
class B extends A
{
A::setX();
}
is a little off. You didn't put your call inside of a method.
class B extends A
{
public static function doSomething() {
A::setX();
}
}
This isn't actually doing anything by means of the parent/child relationship. In fact, after you define class A, the call to A::setX() can happen anywhere since it's public and static. This code is just as valid:
class A
{
function isXSet()
{
return X;
}
public static function setX()
{
define('X', 1);
}
}
class B { // No extending!
function isXSet() {
return A::isXSet();
}
}
What you're more likely looking for is parent instead:
class A
{
public function isXSet()
{
return X;
}
protected static function setX()
{
define('X', 1);
}
}
class B extends A
{
public static function doSomething() {
parent::setX();
var_dump( parent::isXSet() ); // int(1)
}
}
A big plus here is that extending classes can access protected methods and properties from the parent class. This means you could keep everyone else from being able to call A::setX() unless the callee was an instance of or child of A.
Related
Say I have a class...
class Parent {
protected function foo() {
static $x = 0;
$x++;
return $x;
}
}
... and these two child classes:
class ChildOne extends Parent {
public function bar() {
echo $this->foo();
}
}
class ChildTwo extends Parent {
public function bar() {
echo $this->foo();
}
}
Even though there is only one static variable declared, both ChildOne and ChildTwo are keeping their own record of $x, so the following...
...
$childOne.bar();
$childTwo.bar();
... is producing the output '11' instead of '12'.
Question: Is it possible to ensure that all child classes are using the same static variable when calling a parent method? The solution would produce an output of '12' in the example above without implementing a class property.
No answer leads me to believe this simply isn't possible. For future reference to others, here is what I implemented:
class Parent {
static $x = 0;
protected function getX() {
self::$x++;
return self::$x;
}
}
class ChildOne extends Parent {
public function bar() {
echo $this->getX();
}
}
class ChildTwo extends Parent {
public function bar() {
echo $this->getX();
}
}
...
$childOne.bar();
$childTwo.bar();
Output is '12' as required, but had to implement the static class property.
try referring to the parent. say getX() returns a string
class ChildTwo extends Parent {
public function bar() {
$tempOfX $parent->getX();
echo($tempOfX);
}
}
How do you access a child method eg.?
class A
{
public function Start()
{
// Somehow call Run method on the B class that is inheriting this class
}
}
class B extends A
{
public function Run()
{
...
}
}
$b = new B();
$b->Start(); // Which then should call Run method
Class A should not try to call any methods that it itself does not define. This will work just fine for your scenario:
class A {
public function Start() {
$this->Run();
}
}
However, it will fail terribly should you actually do this:
$a = new A;
$a->Start();
What you're trying to do here sounds very much like a use case for abstract classes:
abstract class A {
public function Start() {
$this->Run();
}
abstract function Run();
}
class B extends A {
public function Run() {
...
}
}
The abstract declaration will precisely prevent you from shooting your own foot by trying to instantiate and Start A without extending and defining required methods.
If B is inherited from A then B will be like:
class B extends A
{
public function Start()
{
...
}
public function Run()
{
...
}
}
So as Run() and Start() are in the same class, we can call Run() in Start() directly.
public function Start()
{
Run();
}
I have a base class A:
class A {
public static function a() {
...
}
public static function b() {
...
}
}
and an extended class B
class B extends A {
public static function a() {
...
}
public static function c() {
...
}
}
I would like to be able to call all the methods using B::
How would I call A::b, using B::?
You should be able to accomplish this as easily as:
class B extends A {
public static function a() {
parent::a();
}
}
See the docs
Whats wrong with me OOP here.
I want to inherit from Class A
The return_output method will do something common so I don't want to write that in the inherited classes.
However when I do B->return_output() I want it to run the do_something method in Class B, but I see that it always runs the method from Class A.
Should I replace $this with something else?
class A {
private function do_something() {
// do something
}
public function return_output() {
$op = $this->do_something();
// add some wrappers to $op
return $op;
}
}
class B extends A {
private function do_something() {
// do something different
}
}
var newClass = new B;
echo B->return_output();
use protected and not private since you are running it inside of scope a and scope b can't access private scope a:
class A {
protected function do_something() {
echo('ado_something');
}
public function return_output() {
$op = $this->do_something();
// add some wrappers to $op
return $op;
}
}
class B extends A {
protected function do_something() {
echo('bdo_something');
}
}
$newClass = new B;
echo $newClass->return_output();
I have a base class with many sub-classes, and a generic function to cache the results of a function. In the cache function, how do I figure out what sub-class was called?
class Base {
public static function getAll() {
return CacheService::cached(function() {
// get objects from the database
});
}
}
class X extends Base {}
class Y extends Base {}
class Z extends Base {}
class CacheService {
function cached($callback) {
list(, $caller) = debug_backtrace();
// $caller['class'] is always Base!
// cannot use get_called_class as it returns CacheService!
// see if function is in cache, otherwise do callback and store results
}
}
X::getAll();
Z::getAll();
If you're using PHP >= 5.3, you can do this with get_called_class().
Edit: To make it more clear, get_called_class() has to be used in your Base::getAll() method. You, of course, would then have to tell CacheService::cached() what class this reported (adding a method argument would be the most straight-forward way):
class Base {
public static function getAll() {
return CacheService::cached(get_called_class(), function() {
// get objects from the database
});
}
}
class X extends Base {}
class Y extends Base {}
class Z extends Base {}
class CacheService {
function cached($caller, $callback) {
// $caller is now the child class of Base that was called
// see if function is in cache, otherwise do callback and store results
}
}
X::getAll();
Z::getAll();
Try using the magic constant __CLASS__
EDIT: Like this:
class CacheService {
function cached($class, $callback) {
// see if function is in cache, otherwise do callback and store results
}
}
class Base {
public static function getAll() {
return CacheService::cached(__CLASS__, function() {
// get objects from the database
});
}
}
FURTHER EDIT: Using get_called_class:
class CacheService {
function cached($class, $callback) {
// see if function is in cache, otherwise do callback and store results
}
}
class Base {
public static function getAll() {
return CacheService::cached(get_called_class(), function() {
// get objects from the database
});
}
}