Строгие стандарты уведомления Вид / Схема расположения

1

Я получаю головную боль с уведомлениями php "Строгие стандарты" в классе:

Родительский класс:

class View {

    /**
     * 
     * @param string $viewFolder
     * @param string $viewBasename
     * @return boolean
     */
    public static function exists($viewFolder, $viewBasename){
        $exists = false;
        if(\is_string($viewFolder) && \is_string($viewBasename)){
            $exists = \is_file(\APPLICATION_PATH."View/$viewFolder/$viewBasename.phtml");
        }
        return $exists;
    }

    /**
     * 
     * @param string $viewFolder
     * @param string $viewBasename
     * @param array $viewVariables
     */
    public static function load($viewFolder, $viewBasename,array $viewVariables = []){
        extract($viewVariables);
        require \APPLICATION_PATH."View/$viewFolder/$viewBasename.phtml";
    }

}

Класс ребенка:

class Layout extends View{

    /**
     * 
     * @param string $viewBasename
     */
    public static function exists($viewBasename) {
        return parent::exists('_layout', $viewBasename);
    }

    /**
     * 
     * @param string $viewBasename
     * @param array $viewVariables
     */
    public static function load($viewBasename, array $viewVariables = array()) {
        parent::load('_layout', $viewBasename, $viewVariables);
    }

}

Я прочитал эту тему, и теперь ясно, что причиной являются те недостающие параметры в методах дочерних классов. Декларация методов должна быть совместима с родительскими методами в PHP

Есть ли способ избавиться от этих уведомлений без отключения сообщений об ошибках или, может быть, лучше подходит для этого?

Заранее спасибо.

Теги:
oop

1 ответ

1
Лучший ответ

Лучший подход - написать свои классы чистым и разумным способом. Что касается практики ООП, то ваши дочерние классы, которые должны расширять родительские методы, должны переопределять их в том же формате (отсюда ваше предупреждение от PHP).

В вашем примере ваш общий рабочий процесс для реализации метода exists() выглядит следующим образом:

  1. Родительский класс имеет метод exists с папкой и именем файла
  2. Класс Child режут углы, потому что он уже знает свою папку и принимает только имя файла
  3. Класс Child передает предопределенную переменную родительскому методу

Если вы посмотрите на это объективно, ваша цель состоит в том, что представление должно иметь возможность вызывать метод exists() в классе Layout и передавать только один параметр, поэтому вы спрашиваете "как я могу удалить требование для передачи папки? " Вот несколько вариантов:

1: передать имя папки в качестве второго аргумента и сделать ее необязательной в реализации класса макета (дочернего):

# Class: Layout
/**
 * @param string $viewBasename
 * @param string $viewFolder
 */
public static function exists($viewBasename, $viewFolder = '_layout') {
    return parent::exists($viewBasename, $viewFolder);
}

# Class: View
public static function exists($viewBasename, $viewFolder) {
    // essentially you swap around the order of the params
}

2: Не проходите в папке вообще, но используйте свойство класса в дочернем элементе и используйте последние статические привязки:

# Class: Layout
/**
 * Define the folder for your layouts
 * @var string
 */
const VIEW_FOLDER = '_layout';

Реализация exists() остается такой же, как и в вашем примере.

# Class: View
public static function exists($viewBasename) {
    // Get your folder from a child instead of an argument
    $viewFolder = static::VIEW_FOLDER;

    $exists = false;
    if(\is_string($viewFolder) && \is_string($viewBasename)){
        $exists = \is_file(\APPLICATION_PATH."View/$viewFolder/$viewBasename.phtml");
    }
    return $exists;
}

Обратите внимание, что вы также можете использовать функцию вместо константы, либо абстрактную в классе View, либо нет, например:

# Class: View
abstract class View {
    /**
     * This method should be defined in children to provide the layout name.
     * Using an abstract method would ensure that it is defined by children,
     * however if View is going to be used on its own then do not use this approach.
     * @return string The view folder name
     */
    abstract protected static function getViewFolder();

    public static function exists($viewBasename) {
        // Get view folder from the children (same as the constant example)
        $viewFolder = static::getViewFolder();
        // ...
    }
}

# Class: Layout
class Layout extends View {
    protected static function getViewFolder() {
        return '_layout';
    }
    public static function exists($viewBasename) {
        return parent::exists($viewBasename);
    }
}

Честно говоря, постоянный вариант немного короче, и они по сути делают то же самое, кроме того, если вы используете функцию вместо константы, вы сможете определить логику манипуляции, если это необходимо.


Если бы я был вами, я бы использовал константу класса для папки вида и вынул ее в качестве аргумента. Затем вы должны использовать static::VIEW_FOLDER вместо аргумента, переданного в load и exists.

  • 1
    Хорошие советы. Спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню