«

»

Mar 25

Print this Post

php constant() function

Even though I’ve been creating PHP applications and small pages for few years there are still lots of surprising and sometimes magic abilities of this language. Some of them we heard from other programmers. Some we discover during our daily work. Today I’d like to share with you about a built-in function which the way I learnt it was exactly what I’ve written before: a magic function that helped me to solve a little issue in our Wikia codebase.

The case looked like that:

class A {
  const TYPE_A = 1;
  const TYPE_B = 2;
  const TYPE_C = 3;
  const TYPE_D = 4;
  const TYPE_E = 5;

  public static function isValid($text, $type) {
    //...
  }
}

class B {
  protected $user = null;

  public function __construct($user) {
    //...
  }

  public function isUsersNameBlocked() {
    return $this->isOkWithA($this->user->getName(), A::TYPE_B);
  }

  public function isUsersNickBlocked() {
    return $this->isOkWithA($this->user->getNick(), A::TYPE_C);
  }

  public function isUsersOccupationBlocked() {
    return $this->isOkWithA($this->user->getOccupation());
  }

  protected function isOkWithA($text, $type = null) {
    $type = is_null($type) ? A::TYPE_A : $type;
    if( class_exists('A') ) {
      return A::isValid($text, $type);
    }

    return true;
  }
}

It turned out one of our wikis doesn’t have the extension “X” which includes the class “A” above and therefore extension “Y” and its class “B” had a logic error within. There had been a thought that it could happen and that’s why the author added the “if” block in isOkWithA() method. But it wasn’t enough. First call to “A” class was before the “if” block and even earlier in other “B” methods (isUsersNameBlocked(), isUsersNickBlocked())!

The hacky way would be replace the class constants with integers before our “secure if” statement. But it wasn’t good idea since later the constants values may change and no one who changes them will think about B class.

We could also re-design everything and maybe put those methods in the A class or introduce some hooks functions. Well, it needed consultation and discussions about how solid and proper is the idea and what the best way to implement and release it is. We could have planed it for later and still needed a quick fix to stop the only one wiki polluting our log with the fatal errors.

I came with a simple solution. I wanted to pass a string parameter in the methods of the B class instead of the constants of the A class. But something like that didn’t work:

//...
public function isUsersNameBlocked() {
  return $this->isOkWithA($this->user->getName(), 'TYPE_B');
}

public function isUsersNickBlocked() {
  return $this->isOkWithA($this->user->getNick(), 'TYPE_C');
}

protected function isOkWithA($text, $type = null) {
  if( class_exists('A') ) {
    $type = is_null($type) ? A::TYPE_A : A::$type;
    return A::isValid($text, $type);
  }

  return true;
}
//...

But then we tried to get to static property of A class not its constant. I tried a little more tricks which are possible thanks to rich syntax of PHP but it ended with nothing. Finally, after short googling the Internet the built-in function constant() was discovered! :) And I changed these parts of code:

class B {
  public function isUsersNameBlocked() {
    return $this->isOkWithA($this->user->getName(), 'TYPE_B');
  }

  public function isUsersNickBlocked() {
    return $this->isOkWithA($this->user->getNick(), 'TYPE_C');
  }
  
  protected function isOkWithA($text, $type = null) {
    if( class_exists('A') ) {
      $type = is_null($type) ? A::TYPE_A : constant("A::$type");
      return A::isValid($text, $type);
    }

    return true;
  }
}

This solution still looks a bit hacky but it’s better than passing directly integers, I think. However it’s still error-prone and in the long term actions we will probably change a little bit the architecture of the extension.

It does seem PHP has really interesting built-in functions. Maybe they are a little bit hacky but they are making PHP flexible, aren’t they?

Permanent link to this article: http://blog.lukaszewski.it/2012/03/25/php-constant-function/

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>