Запитання, на які повинен відповідати кожен хороший розробник PHP [закрито]


75

Я переглядав питання кожного хорошого розробника .Net, маючи можливість відповісти, і був вражений змістом та підходом до цього питання, і тому в тому ж дусі я задаю це питання розробнику PHP.

Як ви думаєте, на які питання повинен відповісти хороший програміст PHP?

РЕДАГУВАТИ : Я позначаю це питання як wiki-спільноту, оскільки воно не є специфічним для користувача і воно спрямоване на служіння спільноті програмістів у цілому.

Чекаємо дивовижних відповідей.

ПРИМІТКА . Будь ласка, дайте відповіді на запитання, як пропонується в коментарях, щоб люди також могли дізнатися щось нове щодо мови.


1
Схожий питання тут, про «загальних помилок для PHP програмістів , щоб уникнути»: stackoverflow.com/questions/1186957

Відповіді:


50

Щоправда, я вкрав це питання звідкись ще (не пам’ятаю, де я його вже читав), але вважав це смішним:

Q: Що таке T_PAAMAYIM_NEKUDOTAYIM?
В: Оператор роздільної здатності (подвійне двокрап’я)

Досвідчений PHP'er відразу знає, що це означає. Менш досвідчені (і не єврейські) розробники можуть захотіти прочитати це .

Але більш серйозні питання зараз:


З: Що є причиною цього попередження: «Попередження: Не вдається змінити інформацію заголовка - заголовки вже надіслані», і яка хороша практика для запобігання цьому?
В: Причина: дані тіла були надіслані, що спричинило надсилання заголовків.
Запобігання. Перш ніж виводити будь-які дані тіла, спочатку виконайте певний код заголовка. Переконайтеся, що ви випадково не розіслали пробіли чи будь-які інші символи.


З: Що неправильно з цим запитом "SELECT * FROM table WHERE id = $_POST[ 'id' ]":?
В: 1. Це вразливо для введення SQL. Ніколи не використовуйте введення даних користувача безпосередньо у запитах. Спочатку продезінфікуйте. Переважно використовувати підготовлені твердження ( PDO ) 2. Не виділяйте всі стовпці (*), а вказуйте кожен окремий стовпець. Це головним чином для запобігання запитам, що призводять до збільшення пам’яті, коли, наприклад, у певний момент додається стовпець BLOB.


З: Що поганого в цьому, якщо твердження if( !strpos( $haystack, $needle ) ...:?
A: strpos повертає індексну позицію місця, де він вперше знайшов $ голку, яка могла б бути 0. Оскільки 0також вирішує falseрішення полягає у використанні суворого порівняння:if( false !== strpos( $haystack, $needle )...


З: Який найкращий спосіб написати це твердження if, і чому?
if( 5 == $someVar )або if( $someVar == 5 )
A: Перший, оскільки він запобігає випадковому присвоєнню 5 до $ someVar, коли ви забудете використовувати 2 рівнознаки ( $someVar = 5), і спричинить помилку, другий - ні.


Q: Враховуючи цей код:

function doSomething( &$arg )
{
    $return = $arg;
    $arg += 1;
    return $return;
}

$a = 3;
$b = doSomething( $a );

... яке значення $aі $bпісля виклику функції і чому?
В: $a є 4і $bє 3. Перший, оскільки $ arg передається за посиланням, другий, оскільки повернене значення функції є копією (а не посиланням на) початкового значення аргументу.


ООП специфічний

Питання: В чому різниця між public, protectedі privateу визначенні класу?
В: public робить учасника класу доступним для всіх, protectedробить учасника класу доступним лише для себе та похідних класів, privateробить учасника класу доступним лише для самого класу.


З: Що не так із цим кодом:

class SomeClass
{
    protected $_someMember;

    public function __construct()
    {
        $this->_someMember = 1;
    }

    public static function getSomethingStatic()
    {
        return $this->_someMember * 5; // here's the catch
    }
}

В: Статичні методи не мають доступу до $ this, оскільки статичні методи можна виконувати без створення класу.


З: У чому різниця між інтерфейсом та абстрактним класом?
В: Інтерфейс визначає контракт між реалізовуючим класом і об'єктом, який викликає інтерфейс. Абстрактний клас заздалегідь визначає певну поведінку класів, які його розширюватимуть. До певної міри це також можна вважати контрактом, оскільки він гарантує існування певних методів.


З: Що поганого в класах, які переважно визначають геттери та сетери, які відображають прямо до своїх внутрішніх членів, фактично не маючи методів, які виконують поведінку?
В: Це може бути запах коду, оскільки об’єкт діє як облагороджений масив без особливого використання.


З: Чому реалізація PHP використання інтерфейсів неоптимальна?
В: PHP не дозволяє визначити очікуваний тип повернення методу, що по суті робить інтерфейси досить марними. :-P


28
На strposзапитання, на яке я б не зміг відповісти, не піднявши очі php.net/strpos. Я не відчуваю потреби витрачати мозольний простір на запам'ятовування повного хаосу, який є основним набором функцій PHP, які повертають -1, які помилкові, які нульові, а які - щось зовсім інше. Втім, інші питання я вважаю добре.
Пекка

19
Пекка: Але ви повинні знати, що рядки індексуються нулем, і тому strpos повинен мати можливість повернути нуль для знайденого префікса.
Draemon

5
Вибачте, але ... -1. Ці запитання перевіряють лише базові знання, такі як модифікатори доступу або різниця між методами / полями класу '(статичний) та об'єктом (динамічні). Крім того, ці запитання не перевіряють ніяких навичок мислення (вибачте, я не знаю хорошого англійського слова, щоб пояснити це). Я маю на увазі те, що ви не перевіряєте, чи здатний програміст створювати нестандартні алгоритми тощо
Крозін

36
При всій повазі, T_PAAMAYIM_NEKUDOTAYIMце нікчемна перевірка відповідних знань.
Семпсон

30
5 == $someVarОдин дурний питання. Не маю уявлення, чому цей стиль кодування отримує стільки слави, коли він за своєю суттю недосконалий.
Незадоволений Козел

24

Остаточно питання безпеки!

(прості відповіді в цій публікації, звичайно, захист веб-програм php набагато складніший)

  • як боротися з ін'єкцією SQL?

mysql_real_escape_string () для початку з MySQL. Потім спробуйте навчитися PDO, щоб скористатися підготовленими виписками та переносимістю серед постачальників баз даних.

  • як боротися з CSRF (підробка між запитами між сайтами)?

Додайте маркер до кожного важливого запиту, щоб захистити важливі операції (користувач повинен бачити форму перед відправкою важливого запиту).

  • як мати справу з XSS (міжсайтовими сценаріями), відображеним та збереженим?

htmlentities () - це добре для початку.

  • варіант ін’єкцій XXX: ін’єкція LDAP, ін’єкція XPath тощо ...?

Ви повинні знати, що таке "словниковий запас", який використовується XXX, а потім відняти те, що потрібно для дезінфекції та / або "перевірити та відхилити".

  • який перелік розумних функцій?

Функції, які інтерпретують PHP-код (можливо, включений у віддалений файл) або виконують команду у вашій системі. Короткий і неповний список може бути: exec (), passthru (), system (), popen (), eval (), preg_replace () ...

  • як боротися з небезпекою включення файлів?
  • що таке поперечний шлях?
  • які ризики пов'язані із завантаженням файлів?

Потрібна ретельна перевірка параметрів, що використовуються при відкритті файлу або віддалених ресурсів.

  • як застосувати конфігурацію вашої конфігурації PHP (тобто чи знаєте ви, що корисно з php.ini)?

Це буде довго, тому я пропускаю відповідь, будь ласка, прочитайте керівництво PHP.

  • про фільтрування даних користувачів: у чому різниця між санітарною обробкою та реєстрацією та відмовою ?

Перший перетворює вступ у щось менш вороже. Другий перевіряє, чи правильний впис, і якщо не відмовляє.


Хоча я погоджуюсь, що ви повинні знати, як боротися з введенням SQL, якщо це доречно, чому ви вважаєте, що це необхідно для ВСІХ хороших програмістів PHP? Не скажу, що я добре працюю з PHP, але написав веб-додаток, який не мав нічого спільного з SQL, і спроба введення SQL могла б провалитися. Я знаю, що й інші займаються подібною роботою. (FYI, додаток обробляв та графікував наукові дані, які погано вписувалися в базу даних SQL.)
GreenMatt

Ну, питання трохи "розпливчасте", і оскільки більшість програм PHP (веб) потребують бази даних, я включив матеріали SQL.
Kartoch

4
+1. хоча відповідь на більшість: використовувати належний фреймворк або бібліотеку ...
back2dos

14

"Чому ви не використовуєте щось інше?"

Вибачте, хтось повинен був це сказати :)


24
Я думаю, це справді хороше питання. Розробники повинні мати можливість пояснити, чому вони вибрали одну мову / фреймворк замість іншої, і відповідь не повинна бути "тому, що я ніколи нічого не пробував". PHP має переваги та недоліки порівняно з альтернативами, і, всупереч поширеній (або, можливо, елітарній) думці, є поважні причини для його використання.
JAL

1
це дуже хороше питання ... хоча мені не подобається PHP, я вважаю, що існує маса вагомих причин використовувати його за певних обставин ...
back2dos

2
Мене точно запитували в інтерв’ю для роботи в PHP / LAMP. Я згоден, що це слушне запитання.
markb

12

Чи є крос-браузер php?

(я знаю, це викликає сміх у багатьох людей, але це питання, яке частіше задається на форумах PHP!)


9
+1. я не знаю, сміятися чи плакати ...: D
back2dos

зазвичай я думаю, що "це те, що ми отримали для вибору найпопулярнішої мови веб-програмування"
Strae

11

Думаю, гарним питанням було б: як працює HTTP? Робота з іншими даними HTTP-комунікаціями GETта POSTданими є невід'ємною частиною розробки PHP. Розуміння того, як працює HTTP в ширшому контексті, і те, як PHP реалізує це, дуже далеко.


9

У чому різниця між == та === і чому ви взагалі хочете використовувати ==?


1
Тому що якщо ви вже знаєте тип змінної, яку ви використовуєте, немає необхідності в накладних витратах на перевірку типу в порівнянні. Якщо ви не знаєте, який тип вашої змінної, тоді у вас є більші проблеми, ніж використання неправильного компаратора.
Mike

1
'===' працює швидше, ніж '=='
Етешем

1
'==' є рівними, але не обов'язково однакового типу, а '===' означає, що вони рівні та однакового типу. Наприклад, цей код: <? Php if (true == "true") {echo 'first'; } if (true === "true") {echo 'second'; }?> буде виводитись лише першим, оскільки "true" - це рядок і true.
zuzuleinen

9

Поясніть, чому 2.5замість 3:

$a = 012;
echo $a / 4;

Відповідь: Коли перед числом 0у PHP стоїть число, число розглядається як вісімкове число (база-8). Тому вісімкове число 012дорівнює десятковому числу 10.


8

Це ще ніхто не торкався, але це те, про що кожен розробник PHP повинен мати можливість довго говорити: Чому це register_globalsпогано?


Насправді, я сподіваюся, що для цього не потрібно довго говорити ... одного-двох речень має бути достатньо для цієї жахливої ​​ідеї!
JAL

2
register_globalsнастільки ж поганий, як розробник, який використовує змінну без попереднього її визначення.
Маттео Ріва

7

Коли веб-сайт розробляється за допомогою php, і це абсолютно глупо, це:

а) помилка PHP

б) Помилка програмістів


Я вважаю, що це справедливо. Я бачив, як багато нових розробників автоматично звинувачують мову / компілятор / інтерпретатор, коли їхнє безпосереднє припущення полягає в тому, що це вони. PHP має більше ніж справедливу частку нових розробників, тому це, мабуть, актуально.
Draemon

1
Помилка програміста, незмінно. Поки у вас є одна успішна реалізація, здійснена з відповідною мовою / платформою. Вікіпедія виділяється серед тисяч інших. PHP може мати свої недоліки, але його успіх не заперечується.
kprobst

2
@Felix: Багато людей звинувачують PHP в тому, що сайт X або Y страшний, коли очевидно, що це вина програмістів. PHP робить те, що ви наказали йому робити, це не магічно, він не має власного розуму.
AntonioCS

Але де суть того, що хороший розробник PHP повинен мати можливість відповісти на це питання? Кожен хороший програміст знає, що якщо щось не працює, це, швидше за все, його вина, а не мова. І якщо хтось звинувачує PHP, все одно можна сказати: "Ну, це мова експертів" :-D
Фелікс Клінг

3
але PHP є магічним: magic_quotes_gpc
Draemon

6

Яка найкраща практика уникати введення даних користувача? (Це питання, схоже, часто виникає)


10
Звичайно, це фокус. Це вихід, який потребує екранування, а не введення. Той, хто пропонує "дезінфікувати" або уникнути всього в масиві $ _GET, зробив це неправильно.
bobince

1
@bobince Незважаючи на те, що я погоджуюся з частиною того, що ви отримуєте, як щодо ін'єкцій SQL? Або ви вважаєте, що це частина результату?
Джордан С. Джонс,

2
@bobince неправильно. Потрібно уникнути введення до взаємодії db. Звичайно, якщо ви використовуєте збережені процесори як хороший маленький розробник, це стає непотрібним (якщо ви не використовуєте параметри для генерації та запуску динамічного SQL на SQL-сервері, у цьому випадку вам слід повернутися назад і працювати в технічній підтримці). відділ)
3Dзалишити

6
Це не питання вводу / виводу. Ви повинні бути інформовані про контекст даних рухається в . Якщо це запит SQL, його потрібно захищати в один бік, якщо це вихід HTML, його потрібно уникати в інший спосіб, якщо це URL-адресу, його потрібно екранувати ще в інший спосіб і т. Д. Небезпека, яку, на мою думку, підкреслював bobince, була, якщо ви втекли дані в точці введення для одного контексту, а згодом їх використовувати в іншому, ви все ще вразливі.
Draemon

3
використовуйте фреймворк, щоб зробити це для вас ... рівень абстракції db захистить вас від ін'єкцій ... правильний рендеринг HTML уникне виводу ...
back2dos

6
  • При виклику елемента "name" масиву $, що правильно ?:

    • $array[name]
    • $array['name']

    І те, і інше часто спрацьовує, але правильним є лише вказана форма. define('name', 0);і спостерігати, як жуки літають. Я бачив це занадто багато.

  • Як можна змусити елементи форми подаватись як масив?

    Додайте порожні дужки до атрибута name: кілька <input type="checkbox" name="checkboxes[]" />елементів будуть перетворені в масив на сервері (наприклад $_POST['checkboxes'][0..n]). Я не думаю, що це на 100% PHP-специфічно, але це, безумовно, перевершує цикл $_POSTдля кожного можливого 'checkboxes'.$iелемента.

  • mysql_, mysqli_ або PDO?

    Тут є лише одна справді неправильна відповідь: бібліотека mysql_ не робить підготовлених висловлювань і більше не може виправдовувати свою здатність до зла. Присвоєння функції, яку, як очікується, буде викликано кілька разів за виконаний запит, - mysql_real_escape_string()це просто сіль у рані.


2
Останній пункт: для цього і передбачається передбачення масивів цінностей. Крім того, не слід використовувати безпосередньо mysql або mysqli. Повинна бути якась абстракція, щоб ви могли в якийсь момент перейти на pgsql (наприклад).
jmucchiello

@jmucchiello - домовилися як про випередження, так і про абстрагування, і тут не винна навіть PHP - це назва функції в бібліотеці C mysql. Можливо, особистий смак та старі шрами, але все одно пахне незграбною виноскою від днів "звичайно, це безпечно, я це двічі цитував" :)
тадамсон

5

"Який ваш улюблений налагоджувач?"
"Який ваш улюблений профайлер?"

Фактичний додаток / ide / frontend не має великого значення, поки він виходить за рамки "блокнота, ехо та мікрочасу ()". Настільки малоймовірно, що ви наймаєте розробника з мільярдів, який постійно пише ідеальний код, і його / її модульні тести виявляють усі помилки та вузькі місця до того, як вони взагалі трапляються, що ви хочете, щоб хтось міг профайлювати та / або перебирати код і знаходити помилки за скінченний час. (Це стосується, мабуть, усіх мов / платформ, але мені здається, що це недостатньо розвинений набір навичок серед розробників php, суто суб'єктивно)


1
Я запрограмував PHP протягом тривалого часу лише в редакторі без жодних проблем. Налагоджувачі не потрібні. Все ядро ​​Linux було написано без доступу до налагоджувача. Налагоджувачі корисні, але зовсім не потрібні. Подібним чином Profilers потрібні лише у випадку, якщо у вас насправді є проблема з часом. Я використовував APD для цього. Але я зазвичай вимикаю APD у своєму php.ini.
jmucchiello

відладчики пришвидшують роботу, а не лише тому, що ви не друкуєте значення вручну. відповідь: xdebuger, якщо не використовувати Zend Studio, а Zend-налагоджувач, якщо ви використовуєте Zend Studio
Йосеф

5

У Террі Чай є публікація в блозі, яка в основному підсумовує те, що кожен розробник PHP повинен знати та / або, як очікується, відповідатиме якоюсь мірою на співбесіді.

http://terrychay.com/article/php-coders.shtml

Я думаю, це чудовий підсумок.


4

Я запитав би щось на зразок:

а) як щодо кешування?

б) як можна організувати кеш?

в) Ви впевнені, що не робите зайвих запитів до БД? (У моєму першому матеріалі, який я зробив на PHP, це був mysql_query всередині foreach, щоб отримати імена користувачів, які коментували ... жахливо :))

г) чому register_globals - це зло?

д) чому і як слід розділяти подання з коду?

f) яка головна мета "реалізації"?

Ось питання, які для мене були зовсім не зрозумілі після того, як я прочитав деякі основні книги. Я дізнався все про ін’єкції та CSX, strpos за кілька днів \ тижнів через тисячі поширених запитань в Інтернеті. Але поки я не знайшов відповіді на ці запитання, мій код був справді жахливим :)


Я погано розмовляю англійською. (Англійська мова не є моєю рідною мовою). Тож, дякую, буду знати.
Ben Usman

Опс, тут була така "готівка". Прошу вибачення.
Ben Usman

3

Чому ви ніколи не повинні виводити дані користувача безпосередньо!

Друк таких речей, як дані з GET, може призвести до уразливостей міжсайтових сценаріїв (XSS) . Ось чому вам слід спочатку надсилати вхідні дані від клієнта через htmlspecialchars ().


а також введення SQL, підробка між запитами (CSRF), введення Command / LDAP / XPath, включає введення, введення файлів ...
Kartoch

Він не є специфічним для php, але застосовується до кожного веб-додатку.
Residuum

2
Це ДУЖЕ специфічно для php, оскільки PHP не має духу "безпечного за замовчуванням" для розробників.
Kartoch

@Kartoch: Ви не повинні вважати, що це робить будь-яка система. Навіть якщо це зачіпає себе цим гаслом. Не довіряйте його безпеці своїй.
jmucchiello

@jmucchiello вибачте, я не зрозумів: PHP - одна з найбільш вразливих веб-мов, але я не мав на увазі, що всі інші захищені.
Kartoch


1

Що не так із наступним кодом?

$a = 2;
function foo()
{
    $a = 3;
}
foo();
echo $a;

Відповідь? Використовуйте 'global $ a;' на початку функції, оскільки $ a у функції є локальним, якщо не використовується глобальний оператор.
Nathan Osman

4
Нічого не буде. Це просто показує область змінних :)
takehin

Але з контексту видно, що результат був не таким, яким передбачався.
Натан Осман,

Єдина проблема полягає в тому, що foo повинен повернути $ a. Крім цього, ви не можете припустити, що щось інше є неправильним.
Чак Берджесс

3
Змініть питання та код. Замість того, щоб сказати: "Що не так із наступним кодом?" змінити його на "Які будуть результати $ a і чому?" Змініть код на такий:$a = 2; function foo() { $a += 3; return $a; } $a = foo(); echo $a;
Чак Берджес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.