Call static class method by static variable

3

In the PHP documentation , I found this code against the scope resolution operator ::

<?php
class OutraClasse extends MinhaClasse {
  public static $meu_estatico = 'variável estática';

  public static function doisPontosDuplo() {
     echo parent::VALOR_CONST . "\n";
     echo self::$meu_estatico . "\n";
  }
}

$classname = 'OutraClasse';
echo $classname::doisPontosDuplo(); // No PHP 5.3.0

OutraClasse::doisPontosDuplo();
?>

By doing a test here, I realized that turning $classname into static attribute and changing the call of the variable like this:

class OutraClasse {
  public static $meu_estatico = 'variável estática';
  public static $classname = 'OutraClasse';

  public static function doisPontosDuplo() {
     echo parent::VALOR_CONST . "\n";
     echo self::$meu_estatico . "\n";
  }

  public static function teste(){
  echo self::$classname::doisPontosDuplo();
  }
}

OutraClasse::teste();

PHP throws the following error:

  

Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)

Why does the first form pass and the second PHP throws a parse error?

Note: When you have an object inside another type $obj1->getObj2->getMetodoObj2 , php does not throw an error.

    
asked by anonymous 14.12.2015 / 18:00

4 answers

8

self only exists within the class. It can not be used outside of it. It indicates that you are referring to something in the class itself. So it gives syntax error, its use is not allowed in this context.

Any construction not allowed by the language gives an error. Perhaps the most basic of these is the syntax error where the compiler already detects that that form of text will not produce a valid code.

The second code placed in the edit is completely wrong. It does not make any sense. Go for the initial example. You have no reason to do what you're trying to do.

And in the new edition (should not be changing) caused another problem. self is the way to name which class you are referring to when you are going to access a member, in this case it is the class itself. So you can not use her name again then self already did this. The syntax is nome_daclasse::nome_do_membro , you have done '' package_name: package_name: member_name% with_self% '. Anything else is invention and unnecessary.

It's no use kicking random things. Language is logic. Just like any language, only in languages, you can make mistakes and people understand if the mistake is not too great. In programming language, any error prevents the operation, the computer is precise.

See working on ideone .

    
14.12.2015 / 18:16
5

As already mentioned, self exists only within the class, such as parent .

The self is used to reference static members of this same class, while parent references methods that this class extends.

The :: operator is used to access static methods and constants defined within the class itself, it means that within the class itself there is no need to reference the class itself by specifying its name class::metodo() , just use the self::metodo() . Although the two forms are correct because they are static methods, and because they are in the class scope, there is no need to reiterate the :: operator when outside the class, whereas static methods and properties are accessible even without instance of the class.

This is wrong in every possible way:

public static function teste(){
  echo self::$classname::doisPontosDuplo();
  }

Using self , the class name does not need to reappear.

public static function teste(){
  echo self::doisPontosDuplo();
  }

This if you do not want to use self :

public static function teste(){
  echo OutraClasse::doisPontosDuplo();
  }
    
14.12.2015 / 18:46
3

The error is triggered due to the conflict in the use of the scope resolution operator (: :)

In the second operator (: :), the compiler understands that it is calling a method from a non-existent class / object, but even before attempting to invoke the object, the compiler must have detected the ambiguity and then triggered an error as a syntax error.

Correction below:

class OutraClasse {
  public static $meu_estatico = 'variável estática';
  public static $classname = 'OutraClasse';

  public static function doisPontosDuplo() {
     //echo self::VALOR_CONST . "\n";
     echo self::$meu_estatico . "\n";
  }

  public static function teste(){
      $c = self::$classname;
  echo $c::doisPontosDuplo();
  }
}


OutraClasse::teste();

We could try calling your test as an attempt to use fluent interface. I can not say because we do not know the real purpose of the test, if it was an attempt to create a fluent interface or it was something accidental. I think it was accidental.

In any case, the code does not make sense. Because self:: represents the object itself, self::$classname contains the name of the same object.

It would make sense if the value of self::$classname was a name of a class other than the name of the current class.

However, I would still have the same syntax error because there is no fluent interface implementation.

    
14.12.2015 / 18:43
2

@bigown has already shown that your code has an error. You used self outside the class.

What happens in your case is Parse Error . This is a limitation of the current PHP versions, which has been fixed in the 7 version, as described here . / p>

But disregarding this, you can do the following forms in PHP for the call to occur correctly.

 call_user_func_array(Classe::$outraClasse, 'MetodoOutraClasse')

You could also use:

 call_user_func
 foward_static_call
 foward_static_call_array

Another thing that could be done is to concatenate the string and, after being saved in a variable, call it a function.

$method = self::$outraClasse . '::doisPontosDuplo'

$method(1, 2, 3);

I already answered a similar question here (I made it myself and I replied):

Syntax error when trying to access static method on object stored in property!

    
14.12.2015 / 18:20