KyelJmD
KyelJmD

Reputation: 4732

Implementing Abstract Methods in PHP error

I have created a class here that contains an abstract method , it always return this errors to me even though that method is declared abstract. Here's my whole code

<?php
interface Validator{
    public function isValid($input);
    public function getErrors();
}

class Validator_AbstractValidator
{
    protected $_errors = array();

    abstract public function isValid($input);

    public function getErrors()
    {
        return $this->_errors;
    }

    protected function _addError($message){
        $this_errors[] = $message;
    }
}

class Validator_MinimumLength extends Validator_AbstractValidator
{
    protected  $_minLength;

    public function __construct($minLength)
    {
        $this_minLength = $minLength;
    }

    public function isValid($input){
         if (strlen($input) > $this->_minLength) {
            return true;
        } else {
            $this->_addError("Input must be at least {$this_minLength}");
            return false;
        }
    }
}

class Validator_NoSpaces extends Validator_AbstractValidator{

    public function isValid($input) {
        if (preg_match('/\s/', $input)){
            $this->_addError("Spaces are not allowed");
            return false;
        }
        return true;
    }
}


interface Form_ElementInterface extends Validator{ }

class Form_Element_AbstractElement extends Validator_AbstractValidator implements Form_ElementInterface
{

    protected $_validators = array();

    public function addValidator(Validator $validator)
    {
        $this->_validators[] = $validator;
    }

    public function getValidators()
    {
        return $this->_validators;
    }

    protected function _addErrors(array $errors)
    {
        foreach ($errors as $error) {
            $this->_addError($error);
        }
    }

    public function hasErrors()
    {
        return (count($this->getErrors()) !== 0);
    }

    public function isValid($input)
    {
        foreach ($this->_validators as $validator) {
            if (!$validator->isValid($input)) {
                $this->_addErrors($validator->getErrors());
            }
        }
        return !$this->hadErrors();
    }
}

class Form_Element extends Form_Element_AbstractElement
{
    public function __construct($value,$minLength = 8)
    {
        $this->addValidator(new Validator_NoSpaces($value));
        $this->addValidator(new Validator_MinimumLength($minLength));
        //...
    }
}

The error is this Fatal error: Class Validator_AbstractValidator contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Validator_AbstractValidator::isValid) in C:\xampp\htdocs\beatbeast\includes\Db\Validator.php on line 21

but line 21 only contains this

}

Is there anything I've missed?

Even though I added the keyward abstract in Class Validator_AbstractValidator class I encountered this problem

Fatal error: Can't inherit abstract function Validator::isValid() (previously declared abstract in Validator_AbstractValidator) in C:\xampp\htdocs\beatbeast\includes\Db\Validator.php on line 57

but once again line 57 only contains this

{

Upvotes: 2

Views: 6443

Answers (3)

I had the same error with the following code :

Interface Fruit
{
   public function getCalories() ;
   public function countSeeds() ;
}

Interface Vegetable
{
   public function getVitamins() ;
   public function getCalories() ;
}

class Tomato implements Fruit, Vegetable
{
   ...
}

Here was my solution, I added a third parent interface.

Interface Food 
{
    public function getCalories() ;
}

Interface Fruit extends Food
{

   public function countSeeds() ;
}

Interface Vegetable extends Food
{
   public function getVitamins() ;
}

class Tomato implements Fruit, Vegetable
{
   ...
}

Upvotes: -1

The Alpha
The Alpha

Reputation: 146191

PHP 5 introduces abstract classes and methods. It is not allowed to create an instance of a class that has been defined as abstract. Any class that contains at least one abstract method must also be abstract. Methods defined as abstract simply declare the method's signature they cannot define the implementation.

if a class is not declared as abstract, it cannot contain any abstract methods.

abstract class Validator_AbstractValidator
{
    //...
}

Update:

class Form_Element_AbstractElement extends Validator_AbstractValidator implements Form_ElementInterface

You are extending an abstract class (Validator_AbstractValidator) and also implementing the interface Validator all together, that is not possible.

Extend the class and implement the interface individually and implement the interface Validator in a separate class, not in Validator_AbstractValidator because it's an abstract class you've already declared before.

Implementing of interface Validator:

class from_validator_interface implement Validator{
    // you have to implement all the methods declared in the interface, in your case
    // `isValid` and `getErrors` both methods have to be implemented
}

Extending of abstract class Validator_AbstractValidator:

class someClass extends Validator_AbstractValidator{
    // you don't need to implement all the abstract methods like interface
}

Some usefull links: php.net, other and more.

Upvotes: 4

takteek
takteek

Reputation: 7110

Your code works fine for me once I add abstract to Validator_AbstractValidator, which you say you already did.

abstract class Validator_AbstractValidator
{ ...

Upvotes: 0

Related Questions