Подготовка за вашето PHP интервю Всичко, което сте искали да знаете за интерфейсите, съвместимостта на подписите и

вашето
Интерфейсите, появили се за първи път в PHP 5, отдавна са заели силно място в обектно-ориентираната (или по-правилно "ориентирана към класа"?) част на езика.

Изглежда - какво може да бъде по-просто от интерфейса? „Сякаш клас, но не клас, не можете да създадете инстанция, а по-скоро договор за бъдещи класове, съдържа заглавките на публичните методи“ – нали, с тези думи най-често отговаряте на дежурния въпрос в интервю за това какво е интерфейс?

Не всичко обаче е толкова просто, колкото може да изглежда на начинаещ PHP програмист. Конвенционалните аналогии не работят, езиковото ръководство ви подвежда, неочаквани клопки дебнат в кода...

Три предишни части:

Какво може да съдържа един интерфейс?

Очевидно публични методи и без внедряване: веднага след заглавката (подписа) на метода трябва да го завършите с точка и запетая:

Малко по-малко очевиден (въпреки че е описан в ръководството) е фактът, че интерфейсът може да съдържа константи (само публични, разбира се!):

Защо константите в интерфейсите не се използват широко в индустриалния код, въпреки че понякога се използват? Причината е, че те не могат да бъдат заменени в производен интерфейс или в клас, който имплементира този интерфейс. Интерфейсните константи са най-постоянните константи в света :)

Какво не може да съдържа един интерфейс?

Нищо друго не може. С изключение на заглавките на публичните методи и публичните константи.

Не може да се включи в интерфейса:

  • Всякакви имоти
  • Непублични методи
  • Приложени методи
  • Непублични константи
Това всъщност той и интерфейсът!

Съвместимост на сигнатурата на метода

За да проучим допълнително интерфейсите, вие и аз трябва да научим за една важна концепция, която е незаслужено пренебрегната в ръководството за PHP: концепцията за „съвместимост на подписите“.

Сигнатурата е описание на функция (метод), което включва:

  • Модификатор на достъп
  • Име на функция (метод).
  • Списък с аргументи, където за всеки аргумент:

  • Тип
  • Име
  • Стойност по подразбиране
  • или оператора "три точки".
  • тип връщане
  • Примери:

    Да предположим, че имаме две функции, A и B. Сигнатурата на функция B се счита за съвместима с A (редът е важен, връзката не е симетрична!) в строгия смисъл, ако:

    Съвпадат идеално

    B добавя аргументи по подразбиране към A

    B стеснява обхвата на A

    Сега, след като въведохме тези три прости правила за съвместимост на дефинициите, е много по-лесно да разберем допълнителните тънкости на интерфейсите.

    Наследяване на интерфейса

    Интерфейсите могат да се наследяват един от друг:

    Наследният интерфейс наследява всички методи и константи, дефинирани в родителския интерфейс от родителския интерфейс.

    В производен интерфейс можете да замените метод от родителския интерфейс. Но само при условие, че или неговият подпис ще съвпадне точно с подписа на родителя, или ще бъде съвместим (вижте предишния раздел):

    PHP има ли множествено наследяване?

    Ако ви бъде зададен такъв въпрос, не се колебайте да отговорите:"да". Един интерфейс може да наследява от няколко други интерфейса.

    Сега видяхте всичко:

    Правила за разрешаване на конфликтиСигнатурите на метода за множествено наследяване са точно същите, както видяхме по-горе:

    Тънкостите на внедряването на интерфейси

    Всъщност след всичко, което вече видяхте, това вече не са тънкости, а по-скоро малки нюанси.

    Първо, наистина извличането на клас от интерфейс се нарича имплементация. Въпросът е, че вие ​​не просто наследявате методи и константи, но трябва да имплементирате тези методи, които са посочени от подписи, да ги попълните с код:

    Важен аспект, който отличава реализацията на интерфейс от наследяването от друг клас, е способността да се внедряват няколко интерфейса в един клас едновременно.

    Какво става, ако различните интерфейси, които класът имплементира, имат един и същ метод (със същото име)? Вижте по-горе - както и при наследяване на интерфейси един от друг, трябва да се спазва принципът на съвместимост на подписите.

    И да. Не се доверявайте на ръководството, което казва:

    Сигнатурите на метода в клас, който имплементира интерфейс, трябва точно да съвпадат със сигнатурите, използвани в интерфейса, в противен случай ще бъде хвърлена фатална грешка.

    Класът, изпълняващ интерфейса, трябва да използва точно същите сигнатури на метода, както са дефинирани в интерфейса. Ако не го направите, това ще доведе до фатална грешка.

    Не е така, важи същото правило за съвместимост:

    Интерфейсът клас ли е? За и против

    Всъщност не. Интерфейсът си е интерфейс, той се различава от клас поне по това, че е невъзможно да се създаде "екземпляр на интерфейс".

    И всъщност, да, те имат много общо в PHP:

    1. Интерфейсите, като класовете, могат да бъдат в пространство от имена.
    2. Интерфейсите, като класовете, могат да се зареждат чрез механизма за автоматично зареждане. Функцията за автоматично зареждане ще бъде предадено пълното имеинтерфейс (с пространство от имена).
    3. Всеки интерфейс има предварително дефинирана константа ThisInterface::class, съдържаща пълното му име
    4. Интерфейс, подобно на клас, може да участва отдясно в оператора instanceof
    5. Интерфейс, подобно на клас, може да бъде определен като тип в подсказване на типа (показващ типа на аргумент или върната стойност на функция)

    Какво да прочетете вечерта преди важно интервю за работа?

    Разбира се, езиковото ръководство:

    Успех с интервюто и работата!

    Hardcore conf в C++. Каним само професионалисти.

    Чете сега

    JS-PHP MVC интерфейс - обединяване на всичко

    PHP - ООП или процедурен подход

    Използвате ли наследяване на множество интерфейси в PHP?

    Коментари 34

    Оо ... далеч от първата година в PHP, но не знаех за наследяването на интерфейси. Искам да кажа, изобщо не мислех, че можете да правите разширения в интерфейса :) Някак си не го срещнах и не ми беше полезно. Ще го сложа в касичката със свръхнеобходими знания, в случай че имате нужда от тях.

    Между другото, моля, посочете за коя версия на PHP говорите. И тогава те ще започнат да посочват типа int в аргументите на метода под 7-ма версия и ще бъдат много изненадани.

    Благодаря за вниманието. Където и да е посочено друго, това се отнася за текущата стабилна версия на PHP. В момента се знае, че е PHP 7.1

    Ако искате да се съсредоточите върху поведението в по-стари версии, обикновено го уточнявам отделно.

    И курсът е същият.

    Просто в света на PHP "най-новата" и "текущата" версия, за съжаление, са много различни.

    Сега не съм толкова активен с клиентски сървъри, но никога не съм срещал сървър на трета страна със 7-ми клон. Само ако го поставят нарочно, а това, уви, не винагиМоже би. Най-големият проект на debian, за който просто няма 7-ма версия, трябва да живее на 5.6 :(

    P.S. Знам за някои статистики, според които повечето сървъри са на 7-ма версия. В реалния свят статистиката не работи, за съжаление.

    Живеем в едни различни „реални светове“.

    Аз също съм разработчик, активно практикувам (включително на основната си работа). Да срещна PHP 5 някъде за мен е като да видя динозавър на улицата. Теоретично е възможно, разбира се, но на практика не се случва :)

    Да те попитам защо си такъв? Какви скрити фобии преди PHP 7 ви карат?

    Не, не, погрешно сте разбрали :) Лично аз съм за новите версии, особено когато носят толкова много полезни неща.

    Може би аз съм такъв, но наистина не съм виждал "обикновени" проекти, създадени още в дните на 5-ти клон, които да бъдат съзнателно актуализирани до 7-ми. Те просто работят... и това е :)

    "Редовен" - имам предвид блогове, малки магазини и т.н. проекти до 10k / ден.

    И така, какво ви спира? $ sudo apt update и готово - вие сте на желаната "седморка".

    Ако преди не сте имали класове, наречени Int или String, няма да има проблеми. Всичко просто ще работи както преди, само 3 пъти по-бързо и 2 пъти по-ефективно на паметта.

    Ако е имало такива класове, преименувайте ги. Правете 10 минути. Добре добре, настройте тестов стенд, като клонирате боен, дайте му различен домейн и изпълнете всички тестове за приемане. 20 минути е добре.

    Или аз нещо не разбирам?

    Като за начало, всяка актуализация изисква проверка за разумност и евентуално някои поправки. Съгласен съм, 7-ми клон е относително съвместим с предишния, но все пак. Обновявах PHP версиите много пъти и мисля, че и вие, така че трябва да знаете, че има такивавнезапни инциденти, които е по-лесно да оставите така.

    Някой трябва да плати за изразходваното време. Поне оценявам времето и усилията си и ще актуализирам малко хора безплатно. Защо клиент би платил за прасе в джоба? Той вече има VDS за абстрактни 1000 рубли / месец е неактивен.

    Всъщност това е основната причина, поради която "простите" проекти могат да останат на 5-та версия за много дълго време. Докато актуализацията не е силно необходима, никой не го интересува.

    Втората точка: актуализирането не винаги е възможно. Например, преди около година исках да актуализирам PHP 5.6 > 7 на Debian 7 на мой собствен проект. Но се оказа, че под тази ОС тя просто не съществува. Танцуването с тамбури е възможно, но защо ми трябва? Актуализацията не е критична, имам достатъчно производителност. Можете да актуализирате операционната система и след това да актуализирате PHP, но отново, защо са ми нужни тези проблеми?

    Третата точка ви беше описана по-долу: ако смятате, че класът Int и String са всичко, което може да попречи на актуализацията, прочетете отново тази страница отново: http://php.net/manual/ru/migration70.incompatible.php

    Веднъж актуализирах PHP 5.3 > 5.4 (привидно) на един сървър на уеб студио с куп малки проекти. И беше такъв ад, че накрая просто върнахме всичко обратно. Понякога надграждането просто не си струва.

    Е, да, не трябва просто да правите актуализация, по-добре е смислено да актуализирате пакетите един по един, ако искате да актуализирате всичко наведнъж. Изведнъж нещо ще полети и тогава потърсете причината.

    прочетете отново тази страница: http://php.net/manual/ru/migration70.incompatible.php

    Слушайте, вече съм превел от 5 на 7 около две дузини проекти с различна сложност. Включително напълно уникални предмети. И никъде не съм имал проблеми и никъде не беше офлайн за повече от три минути и разходите за труд бяха повече от конвенционалнитеняколко човекодни.

    Повтарям въпроса си: добре, какво правя погрешно? какво правя грешно Какво още не знам за PHP, какво знаете вие? Кажи ми, интересно е!

    UPD Подкрепихте вашата карма, може да помогне :) Но моля, никога повече не публикувайте връзки за референтни връзки...