2008-10-20 8 views

ответ

64

Я согласен с gizmo, преимущество в том, что вам не нужно переименовывать его, если вы переименуете свой класс. DRY.

Точно так же, если у вас есть класс ребенка можно назвать

parent::__construct() 

вызвать родительский конструктор. Если далее по дорожке вы меняете класс, наследуемый дочерним классом, вам не нужно менять вызов конструкции родительскому.

Это похоже на небольшую вещь, но отсутствие изменения имени вызова конструктора для классов ваших родителей может создать тонкие (и не столь тонкие) ошибки.

Например, если вы вставили класс в свой heirachy, но забыли изменить вызовы конструктора, вы могли бы начать вызывать конструкторы бабушек и дедушек вместо родителей. Это может часто приводить к нежелательным результатам, которые могут быть трудно заметить.

обратите внимание также, что

В РНР 5.3.3, методы с тем же именем, что и последний элемент пространства имен имя класса больше не будет рассматриваться в качестве конструктора. Это изменение не влияет на классы, не содержащие имен.

Источник: http://php.net/manual/en/language.oop5.decon.php

+10

Стиль конструктора PHP 4.x будет устаревшим в PHP 7.0 и удален в следующем главном выпуске. http://php.net/manual/de/migration70.deprecated.php#migration70.deprecated.php4-constructors – SimonSimCity 2015-10-21 08:42:37

18

__construct был введен в PHP5. Это то, как вы должны это делать сейчас. Однако я не знаю никаких преимуществ .

Из PHP инструкции:

Для обратной совместимости, если PHP 5 не может найти функцию __construct() для данного класса, он будет искать функции конструктора старого стиля, по имени класса. Фактически это означает, что единственный случай, который имел бы проблемы с совместимостью, заключается в том, что у класса был метод с именем __construct(), который использовался для различной семантики

Если вы на PHP5, я бы рекомендовал использовать __construct, чтобы избежать появления PHP в другом месте.

3

В PHP 5 преимущество было бы в том, что производительность будет лучше. Сначала он будет искать конструктор по имени __construct, и если он этого не обнаружит, он будет искать конструкторы по имени className. Поэтому, если он находит конструктор по имени __construct, ему не нужно искать конструктор по имени className.

14

Главное преимущество, которое я вижу для __construct, заключается в том, что вам не нужно переименовывать свой конструктор, если вы измените имя своего класса.

2

Форвардная совместимость. Всегда есть шанс, что прежний код, оставшийся на языке для обратной совместимости, будет удален в будущей версии.

7

Лучшее преимущество использования __contruct() вместо ClassName() является при расширении классов. Гораздо проще называть parent::__construct() вместо parent::ClassName(), так как он многократно используется среди классов, и родительский объект может быть легко изменен.

0

Я думаю, что главная причина в том, что это соглашение о языке. Вам не нужно принуждать язык действовать как кто-то другой.

Я имею в виду, что в Objective-C вы префиксные конструкторы с -init, например. Вы можете создать свой собственный конструктор, используя имя вашего класса, но почему? Есть ли причина использовать эту схему вместо языкового соглашения?

10

Сегодня принятый ответ является устаревшим.

Переименование классов - это плохая практика: вы должны помнить, что и где переименовывать каждый раз при обновлении до более новой версии. Иногда (например, используя Reflection или сложную структуру зависимости) это невозможно без радикального рефакторинга. И это accidental complexity, которого вы хотите избежать. Вот почему в PHP были введены пространства имен. Java, C++ или C# не используют __construct, они используют именованный конструктор, и с ними нет проблем.

В РНР 5.3.3, методы с тем же именем, что и последний элемент имени класса пространство имен больше не будет рассматриваться в качестве конструктора. Это изменение не влияет на классы, не содержащие имен.

Пример

namespace Foo; 
class Test { 
    var $a = 3; 

    function Test($a) { 
    $this->a = $a; 
    } 

    function getA() { 
    return $this->a; 
    } 
} 

$test = new Test(4); 
echo $test->getA(); // 3, Test is not a constructor, just ordinary function 

Обратите внимание, что с именем конструктора не осуждается (PHP 5.5 сегодня). Однако вы не можете предсказать, что ваш класс не будет использоваться в пространстве имен, поэтому__construct следует использовать.

Разъяснение о плохой практике, упомянутой выше (для Dennis)

Где-то в вашем коде вы можете использовать ReflectionClass::getName(); когда вы переименовываете класс, вам нужно запомнить, где вы использовали Reflection, и проверить, остается ли результат getName() в вашем приложении. Чем больше вам нужно помнить что-то конкретное, тем более вероятно что-то забыто, что приводит к ошибкам в приложении.

Родители не могут контролировать все классы в мире, которые зависят от них. Если включено allow_url_include, некоторые другие веб-сайты могут использовать класс с вашего сервера, что может привести к сбою при переименовании какого-либо класса. Это еще хуже в компилируемых языках, упомянутых выше: библиотека может быть скопирована и добавлена ​​в другой код.

Там нет причин, почему переименовать класс:

  • если конфликты имен класса, использование пространств имен
  • если сдвиги класса ответственности, получить какой-то другой класс вместо

В PHP классах в пространстве имен метод с тем же именем следует избегать: интуитивно он должен создать объект, созданный классом; если он делает что-то еще, зачем давать ему одно и то же имя? Это должен быть конструктор и ничего больше. Основная проблема заключается в том, что поведение такого метода зависит от использования пространства имен.

Нет проблем с конструкторами __construct в PHP. Но не самая умная идея изменить именованные конструкторы.

+0

можете ли вы переписать абзац № 2 для ясности? (один из которых начинается с «Переименование ...». Я проиграл, почему плохо переделывать классы, и почему нет проблем с Java, C, C++ и как это имеет отношение к этому вопросу. PHP также должен использовать именованный конструктор как Java, C, C++ или есть проблемы? В чем проблемы? – Dennis 2014-04-24 13:33:22

+1

@Dennis См. Мой обновленный ответ. Он имеет отношение к принятому ответу, потому что Базман не ошибался в переименовании класса: «Я имею в виду вопрос о пространствах имен в его ответе к тому времени, когда я предоставил свой ответ, он позже скопировал его из моего ответа. Теперь он берет кредит, но неважно, он не влияет на самую информацию, и никто не заботится. – 2014-04-25 11:56:05

1

Если есть методы __construct и SameAsClassName, то будет выполняться __construct, метод SameAsClassName будет пропущен.

2

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


Таким образом, в PHP-7 они будут удалить опцию, чтобы создать конструктор как функцию с тем же именем, что и класс. Если вы все еще это сделаете, вы получите E_DEPRECATED.

Вы можете прочитать больше об этом предложении (предложение принято) здесь: https://wiki.php.net/rfc/remove_php4_constructors

И цитата оттуда:

PHP 7 будет излучать E_DEPRECATED всякий раз, когда PHP 4 определяется. Когда имя метода совпадает с именем класса, класс не находится в пространстве имен, а конструктор PHP 5 (__construct) отсутствует, тогда будет испускаться E_DEPRECATED. PHP 8 прекратит выдавать E_DEPRECATED, и методы не будут распознаваться как конструкторы.

Кроме того, вы не получите в PHP-7 в E_STRICT, если вы определяете метод с тем же именем, что и класс и __construct().

Вы можете увидеть это здесь также:

PHP 7 также будет остановки излучающей E_STRICT, когда метод с тем же именем, что и класс присутствует, а также __construct.


Так что я бы порекомендовал вам использовать __construct(), так как у вас будет меньше проблем с этим в будущем.

7

В вашем примере Foo::Foo иногда называют PHP 4 или конструктор старого стиля, потому что происходит от дней PHP 4:

class Foo { 
    // PHP 4 constructor 
    function Foo(){ 
     //do stuff 
    } 
} 

PHP 4 constructors will be deprecated but not removed в PHP 7. Они не будет больше рассматриваться в качестве конструкторов в любой ситуации в PHP 8. Будущая совместимость, безусловно, является большой причиной не использовать эту функцию.