A class constant, class property (static), and class function (static) can all share the same name and be accessed using the double-colon.
<?php
class A {
public static $B = '1'; # Static class variable.
const B = '2'; # Class constant.
public static function B() { # Static class function.
return '3';
}
}
echo A::$B . A::B . A::B(); # Outputs: 123
?>Оператор за резолуција на опсег (::)
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
Оператор за резолуција на опсег (::)
Референца за `language.oop5.paamayim-nekudotayim.php` со подобрена типографија и навигација.
Оператор за резолуција на опсег (::)
The Scope Resolution Operator (also called Paamayim Nekudotayim) or in simpler terms, the double colon, is a token that allows access to a constant, static Операторот за резолуција на опсег (познат и како Paamayim Nekudotayim) или поедноставно, двојната точка, е токен што овозможува пристап до static својство или метод на класа или некој од нејзините родители. Покрај тоа, статичките својства или методи може да се пребришат преку.
доцна статичка врзување
Кога се повикувате на овие ставки од надвор од дефиницијата на класата, користете го името на класата. self,
parent and static).
Можно е да се повикате на класата користејќи променлива. Вредноста на променливата не може да биде клучен збор (на пр.
Paamayim Nekudotayim на почетокот би изгледало како чуден избор за именување на двојна точка. Сепак, додека го пишувале Zend Engine 0.5 (што го напојува PHP 3), така го нарекол тимот на Zend. Всушност значи двојна точка - на хебрејски!
<?php
class MyClass {
const CONST_VALUE = 'A constant value';
}
$classname = 'MyClass';
echo $classname::CONST_VALUE;
echo MyClass::CONST_VALUE;
?>Пример #1 :: од надвор од дефиницијата на класата self, parent and static Три специјални клучни зборови
се користат за пристап до својства или методи од внатрешноста на дефиницијата на класата.
<?php
class MyClass {
const CONST_VALUE = 'A constant value';
}
class OtherClass extends MyClass
{
public static $my_static = 'static var';
public static function doubleColon() {
echo parent::CONST_VALUE . "\n";
echo self::$my_static . "\n";
}
}
$classname = 'OtherClass';
$classname::doubleColon();
OtherClass::doubleColon();
?>Пример #2 :: од внатрешноста на дефиницијата на класата Конструктори и деструктори, ПреоптоварувањеПрепорачаниот начин за избегнување на SQL инјекција е со врзување на сите податоци преку подготвени изрази. Користењето на параметризирани прашања не е доволно за целосно избегнување на SQL инјекција, но тоа е најлесниот и најбезбедниот начин за обезбедување влез во SQL изразите. Сите динамични литерали на податоци во Кога класата што се проширува ја пребришува дефиницијата на родителот на методот, PHP нема да го повика методот на родителот. Зависи од проширената класа дали ќе се повика методот на родителот. Ова се однесува и на Магични
дефиниции на методи.
<?php
class MyClass
{
protected function myFunc() {
echo "MyClass::myFunc()\n";
}
}
class OtherClass extends MyClass
{
// Override parent's definition
public function myFunc()
{
// But still call the parent function
parent::myFunc();
echo "OtherClass::myFunc()\n";
}
}
$class = new OtherClass();
$class->myFunc();
?>Види исто така Пример #3 Повикување на метод на родител.
Белешки од корисници 11 белешки
In PHP, you use the self keyword to access static properties and methods.
The problem is that you can replace $this->method() with self::method() anywhere, regardless if method() is declared static or not. So which one should you use?
Consider this code:
class ParentClass {
function test() {
self::who(); // will output 'parent'
$this->who(); // will output 'child'
}
function who() {
echo 'parent';
}
}
class ChildClass extends ParentClass {
function who() {
echo 'child';
}
}
$obj = new ChildClass();
$obj->test();
In this example, self::who() will always output ‘parent’, while $this->who() will depend on what class the object has.
Now we can see that self refers to the class in which it is called, while $this refers to the class of the current object.
So, you should use self only when $this is not available, or when you don’t want to allow descendant classes to overwrite the current method.It seems as though you can use more than the class name to reference the static variables, constants, and static functions of a class definition from outside that class using the :: . The language appears to allow you to use the object itself.
For example:
class horse
{
static $props = {'order'=>'mammal'};
}
$animal = new horse();
echo $animal::$props['order'];
// yields 'mammal'
This does not appear to be documented but I see it as an important convenience in the language. I would like to see it documented and supported as valid.
If it weren't supported officially, the alternative would seem to be messy, something like this:
$animalClass = get_class($animal);
echo $animalClass::$props['order'];Just found out that using the class name may also work to call similar function of anchestor class.
<?php
class Anchestor {
public $Prefix = '';
private $_string = 'Bar';
public function Foo() {
return $this->Prefix.$this->_string;
}
}
class MyParent extends Anchestor {
public function Foo() {
$this->Prefix = null;
return parent::Foo().'Baz';
}
}
class Child extends MyParent {
public function Foo() {
$this->Prefix = 'Foo';
return Anchestor::Foo();
}
}
$c = new Child();
echo $c->Foo(); //return FooBar, because Prefix, as in Anchestor::Foo()
?>
The Child class calls at Anchestor::Foo(), and therefore MyParent::Foo() is never run.Well, a "swiss knife" couple of code lines to call parent method. The only limit is you can't use it with "by reference" parameters.
Main advantage you dont need to know the "actual" signature of your super class, you just need to know which arguments do you need
<?php
class someclass extends some superclass {
// usable for constructors
function __construct($ineedthisone) {
$args=func_get_args();
/* $args will contain any argument passed to __construct.
* Your formal argument doesnt influence the way func_get_args() works
*/
call_user_func_array(array('parent',__FUNCTION__),$args);
}
// but this is not for __construct only
function anyMethod() {
$args=func_get_args();
call_user_func_array(array('parent',__FUNCTION__),$args);
}
// Note: php 5.3.0 will even let you do
function anyMethod() {
//Needs php >=5.3.x
call_user_func_array(array('parent',__FUNCTION__),func_get_args());
}
}
?>As of php 5.3.0, you can use 'static' as scope value as in below example (add flexibility to inheritance mechanism compared to 'self' keyword...)
<?php
class A {
const C = 'constA';
public function m() {
echo static::C;
}
}
class B extends A {
const C = 'constB';
}
$b = new B();
$b->m();
// output: constB
?>Little static trick to go around php strict standards ...
Function caller founds an object from which it was called, so that static method can alter it, replacement for $this in static function but without strict warnings :)
<?php
error_reporting(E_ALL + E_STRICT);
function caller () {
$backtrace = debug_backtrace();
$object = isset($backtrace[0]['object']) ? $backtrace[0]['object'] : null;
$k = 1;
while (isset($backtrace[$k]) && (!isset($backtrace[$k]['object']) || $object === $backtrace[$k]['object']))
$k++;
return isset($backtrace[$k]['object']) ? $backtrace[$k]['object'] : null;
}
class a {
public $data = 'Empty';
function set_data () {
b::set();
}
}
class b {
static function set () {
// $this->data = 'Data from B !';
// using this in static function throws a warning ...
caller()->data = 'Data from B !';
}
}
$a = new a();
$a->set_data();
echo $a->data;
?>
Outputs: Data from B !
No warnings or errors !It's worth noting, that the mentioned variable can also be an object instance. This appears to be the easiest way to refer to a static function as high in the inheritance hierarchy as possible, as seen from the instance. I've encountered some odd behavior while using static::something() inside a non-static method.
See the following example code:
<?php
class FooClass {
public function testSelf() {
return self::t();
}
public function testThis() {
return $this::t();
}
public static function t() {
return 'FooClass';
}
function __toString() {
return 'FooClass';
}
}
class BarClass extends FooClass {
public static function t() {
return 'BarClass';
}
}
$obj = new BarClass();
print_r(Array(
$obj->testSelf(), $obj->testThis(),
));
?>
which outputs:
<pre>
Array
(
[0] => FooClass
[1] => BarClass
)
</pre>
As you can see, __toString has no effect on any of this. Just in case you were wondering if perhaps this was the way it's done.For the 'late static binding' topic I published a code below, that demonstrates a trick for how to setting variable value in the late class, and print that in the parent (or the parent's parent, etc.) class.
<?php
class cA
{
/**
* Test property for using direct default value
*/
protected static $item = 'Foo';
/**
* Test property for using indirect default value
*/
protected static $other = 'cA';
public static function method()
{
print self::$item."\r\n"; // It prints 'Foo' on everyway... :(
print self::$other."\r\n"; // We just think that, this one prints 'cA' only, but... :)
}
public static function setOther($val)
{
self::$other = $val; // Set a value in this scope.
}
}
class cB extends cA
{
/**
* Test property with redefined default value
*/
protected static $item = 'Bar';
public static function setOther($val)
{
self::$other = $val;
}
}
class cC extends cA
{
/**
* Test property with redefined default value
*/
protected static $item = 'Tango';
public static function method()
{
print self::$item."\r\n"; // It prints 'Foo' on everyway... :(
print self::$other."\r\n"; // We just think that, this one prints 'cA' only, but... :)
}
/**
* Now we drop redeclaring the setOther() method, use cA with 'self::' just for fun.
*/
}
class cD extends cA
{
/**
* Test property with redefined default value
*/
protected static $item = 'Foxtrot';
/**
* Now we drop redeclaring all methods to complete this issue.
*/
}
cB::setOther('cB'); // It's cB::method()!
cB::method(); // It's cA::method()!
cC::setOther('cC'); // It's cA::method()!
cC::method(); // It's cC::method()!
cD::setOther('cD'); // It's cA::method()!
cD::method(); // It's cA::method()!
/**
* Results: ->
* Foo
* cB
* Tango
* cC
* Foo
* cD
*
* What the hell?! :)
*/
?>You use 'self' to access this class, 'parent' - to access parent class, and what will you do to access a parent of the parent? Or to access the very root class of deep class hierarchy? The answer is to use classnames. That'll work just like 'parent'. Here's an example to explain what I mean. Following code
<?php
class A
{
protected $x = 'A';
public function f()
{
return '['.$this->x.']';
}
}
class B extends A
{
protected $x = 'B';
public function f()
{
return '{'.$this->x.'}';
}
}
class C extends B
{
protected $x = 'C';
public function f()
{
return '('.$this->x.')'.parent::f().B::f().A::f();
}
}
$a = new A();
$b = new B();
$c = new C();
print $a->f().'<br/>';
print $b->f().'<br/>';
print $c->f().'<br/>';
?>
will output
[A] -- {B} -- (C){C}{C}[C]<?php
/**
*access a constant from outside a class
*/
class Foo{
public const A = "Constant A";
}
echo Foo::A;
echo "\n";
/**
*access a constant within its own class
*/
class Bar{
public const A = "Constant A";
public function abc(){
echo self::A;
echo "\n";
}
}
$obj = new Bar;
$obj->abc();
/**
*access a constant within her child class
*/
class Baz extends Bar{
public function abc(){
echo parent::A;
}
}
$obj = new Baz;
$obj->abc();
//Static property and static method also follows this principle.