Why only static call return 2?
it seems to me that a class call not by absolute name should depend on the current namespace in the class
<?php
namespace A {
class B {
static function test(){
echo 1;
}
static function check(){
B::test();//1 why?
self::test();//1
static::test();//2
}
}
}
namespace B {
class B extends \A\B {
static function test(){
echo 2;
}
}
}
namespace {
B\B::check();
}
B::test() is executed inside the A namespace and therefore takes the B class, that is provided by the A namespace. Therefore A\B::test is called. The context of the current class is not relevant for that.
The following example shows, that the heredity is irrelevant for this behavior.
<?php
namespace A {
class B {
static function test() {
echo 3;
}
}
class A {
static function test(){
echo 1;
}
static function check(){
B::test();//3
self::test();//1
static::test();//2
}
}
}
namespace B {
class B extends \A\A {
static function test(){
echo 2;
}
}
}
namespace {
B\B::check();
}
static::test returns 2 eventhough you are in the A namespace, because static takes the context from the calling super class and not the current namespace.
self::test returns 1, because self takes the context of the current class instead of the super class.
Related
class A declared at namespace1.
namesapce namesapce1;
class A
{
public static function fun1()
{
}
}
I want to use fun1() inside class B:
namespace namesapce2;
use ???? as fun1
class B
{
public static func2()
{
fun1();
}
}
How to do that ?
namespace namespace2;
use namespace1\A;
class B
{
public static function func2()
{
A::fun1();
}
}
Assuming you're using something that does autoloading or the necessary includes.
Questions says it all really.
I have constants defined in my parent class. I have tried $this->CONSTANT_1 but it's not working.
class MyParentClass
{
const CONSTANT_1=1;
}
class MyChildClass extends MyParentClass
{
// I want to access CONSTANT_1
}
I think you would need to access it like this:
self::CONSTANT_1;
or alternatively "parent", which will always be the value established in the parent class (i.e., the constant's immutability is maintained):
parent::CONSTANT_1;
Interesting
One thing that is interesting to note is that you can actually override the const value in your child class.
class MyParentClass{
const CONSTANT_1=1;
}
class MyChildClass extends MyParentClass{
const CONSTANT_1=2;
}
echo MyParentClass::CONSTANT_1; // outputs 1
echo MyChildClass::CONSTANT_1; // outputs 2
You can also access to constant define in children from parent method, with the static key.
<?php
class Foo {
public function bar() {
var_dump(static::A);
}
}
class Baz extends Foo {
const A = 'FooBarBaz';
public function __construct() {
$this->bar();
}
}
new Baz;
You do not have to use parent. You can use self which would first check if there is constant with the same name in the class itself, then it would try to access the parents constant.
So self is more versatile and provides the possibility to 'overwrite' the parents constant, without actually overwriting it as you can still explicitly access it via parent::.
Following structure:
<?php
class parentClass {
const MY_CONST = 12;
}
class childClass extends parentClass {
public function getConst() {
return self::MY_CONST;
}
public function getParentConst() {
return parent::MY_CONST;
}
}
class otherChild extends parentClass {
const MY_CONST = 200;
public function getConst() {
return self::MY_CONST;
}
public function getParentConst() {
return parent::MY_CONST;
}
}
Leads to the following results:
$childClass = new childClass();
$otherChild = new otherChild();
echo childClass::MY_CONST; // 12
echo otherChild::MY_CONST; // 200
echo $childClass->getConst(); // 12
echo $otherChild->getConst(); // 200
echo $childClass->getParentConst(); // 12
echo $otherChild->getParentConst(); // 12
<?php
class MyParentClass{
const CONSTANT_1=123;
}
class MyChildClass extends MyParentClass{
public static function x() {
echo parent::CONSTANT_1;
}
}
MyChildClass::x();
Live example: http://codepad.org/Yqgyc6MH
Use parent, for example:
class MyParentClass{
const CONSTANT_1=1;
}
class MyChildClass extends MyParentClass{
function __construct(){
echo parent::CONSTANT_1; //here you get access to CONSTANT_1
}
}
new MyChildClass();
OR:
class MyParentClass{
const CONSTANT_1=1;
}
class MyChildClass extends MyParentClass{
MyParentClass::CONSTANT_1; // here you you get access to CONSTANT_1 too
}
You want to use the self keyword.
class Whale
{
const BLOWHOLES = 1;
}
class BlueWhale extends Whale
{
/**
* A method that does absolutely nothing useful.
*/
public function funnyCalculation()
{
return self::BLOWHOLES + 2; // This is the access you are looking for.
}
}
Check the PHP manual for ways to access class constants inside and outside of the class definition.
I have 3 classes..
class 1 :
<?php
include "two.php";
include "three.php";
class One{
public function __construct(){
$two = new Two($this);
$three = new Three($two);
}
}
$api = new One;
?>
class 2 :
<?php
class Two extends AOP {
public function __construct($obj){
//blablabla
}
}
?>
class 3 :
<?php
class Three extends AOP {
public function __construct($obj){
echo get_class($obj);
}
}
?>
But I want the result must output "One".
How to get class name from object inside object?
In your design you have to implement a getter in class two:
class 2 :
class Two
{
private $myObj;
public function __construct($obj)
{
$this->myObj = $obj;
}
public function getMyObj()
{
return $this->myObj;
}
}
then in class 3, you can retrieve class 1:
class Three
{
public function __construct($obj)
{
echo get_class($obj->getMyObj());
}
}
Use the keyword extends to inherit another class. Since PHP does not support multiple inheritances directly. You can get the class that you extend from with parent::$property; or parent::method();. So, you probably want your code to look more like.
// three.php
class Three extends AOP{
public function __construct($obj){
echo get_class($obj);
}
}
// two.php
class Two extends Three{
public function __construct($obj){
parent::__construct($obj); // Constructors do not return a value echo works
}
protected function whatever($string){
return $string;
}
}
// one.php
include 'three.php'; // must be included first for Two to extend from
include 'two.php'
class One extends Two{
public function __construct(){
// change this part
parent::__construct($this); // uses the parent Constructor
echo $this->whatever('. Is this what you mean?'); // call method without same name in this class - from parent
}
}
$api = new One;
I would not use your structure at all, but this should give you an idea of inheritance.
I'm new to OO PHP. Got some questions.
class a {
protected function a1() {
...
}
}
class b extends a {
public function b1() {
...
}
}
Let's say we have 2 classes like explained above. I'm calling b's method like example below
class a {
var $b;
function __construct()
{
$b = new b();
}
protected function a1() {
$b->b1();
}
}
class b extends a {
public function b1() {
...
}
}
I know that, it's possible to call parent class'es method from extended class, but I wonder if reverse way is possible? I mean, calling extended classes method from inside parent class (in this case, class b's method from class a) without declaring in __contruct, simply by $this->b();?
Yes, you can call a method in the extending class.
<?php
class a
{
public function a1 ()
{
$this->b1();
}
protected function b1()
{
echo 'This is in the a class<br />';
}
}
class b extends a
{
protected function b1()
{
echo 'This is in the b class<br />';
}
}
class c extends a
{
protected function b1()
{
echo 'This is in the c class<br />';
}
}
$a = new a();
$a->a1();
$b = new b();
$b->a1();
$c = new c();
$c->a1();
?>
This will result in:
This is in the a class
This is in the b class
This is in the c class
You may also be interested in abstract classes http://us3.php.net/manual/en/language.oop5.abstract.php
use Magic methods of PHP __call or __callStatic
Reference
If I had two classes in separate namespaces (and therefor files), and they both called a function in the global namespace - is there any way to indentify which namespace called that function short of passing the value?
namespace A;
class Test { function run() { \func(); }
...
namespace B;
class Test { function run() { \func(); }
...
function func()
{
// Did a class from "\A" call me or "\B"...?
}
My first thought was to use the __NAMESPACE__ constant. But that is computed in place so it would not solve this problem.
You could define versions of the function in each namespace that then calls func();
namespace A;
class Test { function run() { func(); }
...
namespace B;
class Test { function run() { func(); }
...
namespace A
{
function func()
{
\func(__NAMESPACE__);
}
}
namespace B
{
function func()
{
\func(__NAMESPACE__);
}
}
namespace
{
function func($namespace)
{
//work with $namespace
}
}
debug_backtrace() will show you the call stack. It also gives you the class name of the object that the calls were made from. You could parse this date out and find the namespace.
http://www.php.net/manual/en/function.debug-backtrace.php
function func()
{
$trace = debug_backtrace();
$class = $trace[1]['class']; //Should be the class from the previous function
$arr = explode($class, "\");
array_pop($arr);
$namespace = implode($arr, "\");
}
Let me know if that works. It will probably only work if func() is called from inside an object or class.