Why Does PHP 5.2+ Disallow Abstract Static Class Methods

Why does PHP 5.2+ disallow abstract static class methods?

static methods belong to the class that declared them. When extending the class, you may create a static method of the same name, but you are not in fact implementing a static abstract method.

Same goes for extending any class with static methods. If you extend that class and create a static method of the same signature, you are not actually overriding the superclass's static method

EDIT (Sept. 16th, 2009)

Update on this. Running PHP 5.3, I see abstract static is back, for good or ill. (see http://php.net/lsb for more info)

CORRECTION (by philfreo)

abstract static is still not allowed in PHP 5.3, LSB is related but different.

Abstract Static Function in PHP 5.3

Here's your example

abstract class Table implements iTable {

public static function insert() {
$class = get_called_class();
$sql = 'INSERT INTO '.$class::get_class_name();
echo $sql;
}

}

interface iTable {
static function get_class_name();
}


class ConcreteTable extends Table
{
public function ConcreteTable() {}

static function get_class_name() {
return 'ConcreteTable';
}

}

$t = new ConcreteTable();
$t::insert();

This example respects object paradigm, and you're sure it'll work even if PHP stop support late static bindings (which is a PHP specificity, I think)

Edit: What both answers show is that it's unknown that an abstract class introduces an interface as well for classes extending from it. Following the template pattern, this is possible in PHP even with static functions (albeit for a good reason that gives you strict standard warnings). The proof of concept:

abstract class Table
{
abstract static function get_class_name();
public static function insert() {
printf('INSERT INTO %s', static::get_class_name());
}

}

class ConcreteTable extends Table
{
public static function get_class_name() {
return 'ConcreteTable';
}
}

ConcreteTable::insert();

If you remove the static keywords here, you actually will get useful (and a standard way of doing things) code:

abstract class Table
{
protected $table = NULL;
public function insert() {
printf('INSERT INTO %s', $this->table);
}

}

class ConcreteTable extends Table
{
protected $table = 'ConcreteTable';
}

$table = new ConcreteTable();
...
$table->insert();

Strict standards: Static function model::tableStruct() should not be abstract in

Abstract static methods are kind of an odd concept. A static method basically "hard codes" the method to the class, making sure there is only a single instance (~singleton). But making it abstract means you want to force some other class to implement it.

I see what you are trying to do, but when dealing with abstract classes, I would avoid static methods in the base class. What you can do instead is use late static binding (static::) to call a tableStruct method in the "child" class. This doesn't force the the method to be implemented like abstract does, but you could test for the implementation and throw an exception if it doesn't exist.

public static function foo(){
// call the method in the child class
$x = static::tableStruct();
}

How can i enforce an extending class to have a static method?

Static methods are not part of the object, so they shouldn't be extended.

Make the method concrete.

I actually struggled with this same problem once I started building unit tests (I almost religiously avoid static methods now, but that's a whole side conversation). Check out this question for someone answering your question berr than I can: Why does PHP 5.2+ disallow abstract static class methods?

I can't use a static method, but that seems to be reasonable

Turns out you cannot have static abstract methods on an abstract class. See here:

Why does PHP 5.2+ disallow abstract static class methods?

But you can declare an interface to require a static method.

Here is an example that compiles:

Working Example

<?php
interface IChallenge
{
static function getName();
}

abstract class Challenge implements IChallenge
{

}

class ChallengeType1 extends Challenge
{
public static function getName()
{
return 'Swimming';
}
}

class ChallengeType2 extends Challenge
{
public static function getName()
{
return 'Climbing';
}
}

php abstract classes and interfaces involving static methods?

In most languages, including PHP, you cannot require a class to implement static methods.

This means neither class inheritance, nor interfaces, will allow you to require all implementors define a static method. This is probably because these features are designed to support polymorphism rather than type definition. In the case of static methods you'll never have an object to resolve the type from, so would have to do ClassName::Method explicitly, so the theory is you wouldn't gain anything from polymorphism.

As such, I see three solutions

  1. Declaring the static methods in each class (after all, you are never going to

  2. If you want a method to create instances of your class, but don't want to require an instance to call this method, you could create "Builder" classes to serve this purpose (e.g. OrderBuilder), such that you instantiate an OrderBuilder and call the Create method on this object instead to get Order instances.

  3. (Recommended) Why aren't you simply using the Order constructor?



Related Topics



Leave a reply



Submit