Call static class method by static variable

Asked

Viewed 4,957 times

4

In the PHP documentation, found that code in relation to the target 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();
?>

Taking a test here, I realized that turning $classname in static attribute and change the variable call this way:

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 the first way you pass and the second way PHP throws a parse error?

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

  • 1

    Where have you changed it? How has it changed what has changed?

  • 1

    @bigown edited it. Now netbeans is saying syntax error. Good because I’d like to know why it’s a syntax error too.

  • 1

    In the very PHP documentation that you put in says that 'self' serves to access content from within the class, in this second step you are using outside.

  • 2

    In the first, you make a direct reference to the class OutraClasse and then call the static method ::doisPontosDuplo, already in the second example, the variable - now property - $classname doesn’t even exist.

  • 1

    @Flavioandrade even within the class, error, see the edition.

  • So Diego, as @Edilson put down, the line self::$classname::doisPontosDuplo() does not work even now being inside the class because the self refers to the class itself, so if we translate this your code the result would be something like: OutraClasse::OutraClasse::doisPontosDuplo() what is wrong. In this case either you use only the self self::doisPontosDuplo() or the class name OutraClasse::doisPontosDuplo().

Show 1 more comment

4 answers

10


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

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

The second code placed in the edit is completely wrong. It makes no sense. Go to the initial example. You have no reason to do what you’re trying to do.

And in the new edition (should not keep changing) caused another problem. The self is the way of naming which class is referring when going to access a member, in which case it is the class itself. So you can’t use her name again then the self has already done this. The syntax is nome_daclasse::nome_do_membro, you did ``name_daclasse::name_daclasse::name_do_member. Dentro da classe use self`. Anything else is invention and unnecessary.

No use kicking random things. Language is logic. Just like any language, only in tongues, you can make a mistake and people understand, if the mistake isn’t too big. In programming language, any error prevents the functioning, the computer is accurate.

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

  • I edited, even inside the class, continues from the syntax error.

6

As has already been said, self, exists only within the class, such as the parent.

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

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

This is wrong in every way possible:

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

Using the self, the class name need not reappear.

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

This is if you don’t want to use the self:

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

4

The error is triggered due to 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 trying 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 cannot say because we do not know the real purpose of the test, whether it was an attempt to create an interface or was something accidental. I believe it was accidental.

Anyway, the code doesn’t make sense. Yeah self:: represents the object itself and, self::$classname contains the name of that same object.

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

However, it would still present the same syntax error because there is no implementation of Fluent interface.

3

@Maniero has already demonstrated that your code is wrong. You used self outside the class.

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

But disregarding that, you can do it in the following ways PHP so that the call occurs 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 to a variable, call it as a function.

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

$method(1, 2, 3);

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

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

  • I edited, even internally from the error.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.