RSS
Цитат на деня:"The only real failure in life is the failure to try."

Как да пишем по-добър PHP код

Sun, Nov 30, 2008

Програмиране

Провокиран от блога на един колега, реших да напиша моите виждания над това, как е най-добре да бъде написан един сайт на php.

  • Не използвайте framework-ове - ако питате мен това си е смъртен грях. Да се инклудне такова огромно количество код, само защото програмиста не знае как да си реализира сам решението на задачата си, е направо истинско мъчение за всеки сървър.Не ме разбирайте погрешно, Аз харесвам някои framework-ове, но те винаги реализират много сложни неща и спестяват на програмиста много дни/седмици/месеци работа. Пример за php такъв не мога да дам, защото не съм използвал, но за JavaScript имам добри впечатления от ExtJs.

    Тези които използват framework за да се свържат към базата данни, или каквото и да нормално нещо изискващо 10-15 реда код да се напише (например функции за свързване/изпращане на заявки към база данни), според мен не са php програмисти, защото ако трябва да напишат нещо без framework-а ще го направят по-зле от кучето ми.

    Знам че има хора които просто спестяват 4 мин. работа за тях за сметка на сървъра, и всъщност могат да си го напишат сами на php, така че тук направих голяма генерализация.

    И все пак, по-добър код е този специално написан за даденото приложение, а не framework направен да работи във всяка ситуация, независимо колко знания има използващия го.
  • Не използвайте register_globals и magic_quotes – Има ли нужда от коментар? Много по-добре е да работите без подобни екстри от страна на сървъра. Използването им води до огромни дупки в сигурността, а до някаква степен и натоварва повече сървъра.

    Радвам се че в PHP 6 тези двете ще бъдат премахнати. По-този начин броят на некадърните програмисти би трябвало да намалее. Презирам дори хостове които ги държат включени по подразбиране ;)
  • Отваряйте по една връзка към базата данни – Не мислех че ще се наложи да напиша толкова интуитивно нещо, но напоследък виждам голяма част колеги, които явно от незнание, но се оказва че имат 10-15 връзки към базата по едно и също време от един скрипт. Без коментар!

    Също така е добре да затворите връзката към базата данни ако сте приключили с нея по-рано отколкото ще завърши скрипта ви.
  • Не извиквайте функции в тялото на цикъл – Освен ако не е наложително разбира се. Добър програмист не би трябвало да пише код от рода на:
    for($i=0;$i<count($arr);$i++)
    особено когато има толкова по приятен вариант:
    $arr_len=count($arr);
    for($i=0;$i<$arr_len;$i++)

    Това е често срещан случай, но същото се отнася и за извиквани на функция в while и каквото и да е друго нещо, което ще се изпълни много пъти. Ако е възможно извикването трябва да се извърши преди цикъла.
  • Заграждайте стринговете с единични кавички – При използването на двойни кавички php търси дали в стринга няма променливи които трябва да постави. Това е много бавен процес. Винаги затваряйте стринга с единични кавички и го прекъсвайте когато трябва да включите променлива.

  • Когато достъпвате елемент от масив с ключ стринг, винаги го заграждайте в единични кавички – Имам в предвид, че $arr[key] е няколко пъти по-лош вариант от $arr['key']. Второто е около 7 пъти по-бързо. Разбира се ако имате числов индекс не го заграждайте.
  • Не използвайте операторе за подтискане на грешки - Много бавно и тежко решение да прикриете зле написан код. По-добре го пренапишете без грешки. В малък процент от случаите @ е полезен оператор.
  • Използвайте echo с няколко параметъра – Вместо да напишете нещо от рода на
    echo $x.’ plus ‘.$y.’ equals ‘.($x_$y);
    Можете да го напишете така:
    echo $x,’ plus ‘,$y,’ equals ‘,($x_$y);

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

    Това поведение е валидно само за функцията echo.

  • Използвайте isset() вместо strlen() – Това на много места е казвано. isset() може да се използва много умно и да направи кода ви по-бърз на много места.
  • Избягвайте require_once() и include_once() – Следенето дали даден файл вече е бил инклуднат невинаги е цена която си заслужава да се плати. По добре напишете така кода, че винаги да се инклудва веднъж. Разбира се понякога е невъзможно или прекалено трудно.
  • Избягвайте регулярни изрази – Когато можете да направите нещо без регулярен израз е по добре да го направите така. Избягвайте функции очакващи регулярни изрази като split и ги заменяйте с по-бързите им алтернативи.
  • Използвайте вградените функции на php – Ако има вградена функция която прави това което прави и вашата, по добре е да използвате вградената. Има голяма вероятност вградената да го прави по-ефективно.
  • Декларирайте променлива преди да я използвате – Може да не се вижда, но използването на недекларирана променлива е доста по бавно от варианта в който я декларирате преди да я използвате.
  • ++$i и –$i са по-бързи от $i++ и $i– – Това е така защото вторите, освен че увеличават с едно, запазват старата стойност за да я върнат. Ако знаете какво правят тези оператори ще се досетите защо първите са по-бързи.
  • Не разделяйте кода си на прекалено много функции - Освен ако наистина имате код който ще използвате на много места, разделянето му във функции е безсмислено. Извикването на една функция отнема време колкото 7-8 инкрементации. (само извикването, изпълнанието на е включено ;) )
  • Използвайте ООП умерено – Забелязвам че по-неопитните колеги като научат какво е ООП го използват навсякъде, т.е. където не трябва. Добре е да се знае, че използването ООП не е предимство, освен ако не се решават важни въпроси които не могат да станат по-добре в процедурен стил.

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

Това са част от нещата които се старая да спазвам на продуктивни сайтове. Ако смятате че греша не се колебайте да ме поправите, но по-добре да знаете какво говорите ;)

,

10 Comments For This Post

  1. liquid.sun Says:

    Този пост ми беше изключително полезен. Начинаещ съм естествено. От изброените неща ми се струва, че най-много прекалявам с раздробяването на кода – лош навик от C :)

    Бих добавил само едно единствено нещо. Ефективността е от значение, но и четимостта не трябва да се пренебрегва. Това също е характеристика присъща на добрия код.

  2. Виктор Шапилов Says:

    Хееех ако съм очаквал теб да засека тука… xD
    Нета е малък, както и да е мда наистина е важна тая черта… Налагало ми се е да работя по сайтове преработвани от над 15 души със 15 различни стила на писане, като си бяха оставили пръстите… Но както Асен обича да споменава “зависи за кой го правя, аз моя код си го чета”. :D
    Още не мога да свикна да ползвам стила на шел за цели освен подравняване на каскадни стилове, просто ми е крайно неудобен как си свикнал така не ми е ясно, но ще стигнем и до тази тема следващия път на по бира… :P

    ПП. По статията съм се въздържал от коментар няма какво да коментирам, имаше подобна малко по-подробна статия на английски, в 2-3 сайта съм я чел, но подобно полезно нещо на бг няма. :>

  3. Асен Says:

    Четимостта е важна, но когато кода става по-бавен за изпълнение за сметка на четимостта, следва че програмиста не може да чете ;)

  4. Панчо Гръблев Says:

    Колега, всичко хубаво написано ама така се излагаш с това за фреймуърковете … викни кучето, че ми е интересно да го пробвам 1v1 на PHP :)

  5. Асен Says:

    Е, кой както може но едва ли се излагам защото мога без тях ;)

    Кучето хапе като чуе фреймуърк ;)

  6. Shitung Says:

    Dude, … :) има няколко неща с които не съм съгласен. Това за фреймуорковете – много по удобно е да си го нацъкаш като собствен универсален (доколкото е възможно) фреймуорк, а не всеки път да пишеш едно и също.

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

    Като за край ще кажа една влика мисъл, забравих чия за съжаление:

    “Компютрите са създадени да служат на хората, не хората на компютрите !” :) … замисли се над това и следващия път недей да пестиш 6-7 процесорни итерации, защото има много по умни начини да си оптимизираш кода от към стил на писане, вместо да мислиш коя функция колко итерации повече ще използва. Като сме тръгнали да пестим по 1-2 итерации, защо не си напишем c++ приложение да отваря порт 80, да си обработва GET/POST заявки и да връща резултата, вместо да се тормозим с това тромаво апаче, което обработва всичките 8 HTTP метода, поддържа хиляди други шукарийки и само кафе дето не прави ?! :)

  7. Асен Says:

    Собствена библиотека с класове и функции е задължително за всеки добър програмист. Аз имам в предвид използването на огромни фреймуоркове които лесно могат да не се ползват.

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

    Компютрите правят това което им кажем, ако им кажем да хабят ресурси те ще го направят, при големи сайтове това може да излезе доста скъпо.

  8. Виктор Шапилов Says:

    ********************************
    # Панчо Гръблев Says:
    January 6th, 2009 at 10:34 am

    Колега, всичко хубаво написано ама така се излагаш с това за фреймуърковете … викни кучето, че ми е интересно да го пробвам 1v1 на PHP :)
    ********************************
    Излагация е по-скоро да се твърди обратното… ООП и фреймуърци е добре да се ползват само при нужда и в краен случай. Ако трябва да пътувам до Асеновград с колата, не бих си закачил каравана отзад само защото имала куп удобства…

    @Shitung, относно апачето… Защо се появиха lighttpd подобни алтернативи… Защото е много модно !? ;)

  9. me Says:

    Нищо лошо няма в това да се ползва framework – идеята и целта им е да съберат най-често срещаните практики в програмирането на даден език, често използвани грешки – и всъшност на първо място е – да изолират възможно най-глупавите грешки, които обикновенно програмистите правят.

    Всъщност, на най-първо място е, че с използването и – те предразполага да пишеш по ЕДИН – точно определен стил и начин, така че ако примерно работиш в компания уважаваща себе си и щедяща Q/A екипа си – framework-а е точно за вас.

    Не ме разбирайте обаче погрешно – не говоря за някакви free решения – било то cake или symfony, които са най-популярни. Хванеш ли се да ползваш ИЗЦЯЛО open source си е кофти решение – защото започваш да зависиш от множество външни фактори – а ако трябва да предлагаш стабилна и гарантирана услуга на клиенти – това е out of the question.

    Аз лично мога да ви предложа да си хванете най-добрите програмисти във фирмата, да отделите бюджет и време от примерно два месеца и да направите собствен такъв – подходящ за нуждите ви с оглед на натрупаният ви опит и често срещаните проблеми, с които сте се сблъсквали – но го правете така, че да бъде с идеята за постоянно бъдещо разширение, защото такова ще има… модуларно, без пряко обвързване на обекти с обекти – максимално разчупено (след третият път ще успеете :) )

    Инвестицията ще ви се възвърне многократно в бъдеще – да не говорим, че няма да губите МЕСЕЦИ време за обучение на нов персонал в това как трябва да програмира и как не на даден език. Така изцяло си налагате твърдо ваше ноухау.

    Така направихме ние във фирмата .. вярно загубихме повече време (половин година) защото имаме пипкави програмисти идеалисти :) обаче сега след няколко месеца .. ефекта си личи от далече – най-вече по happy faces на клиентите (80% от всички предишни бъгове изчезнаха и повече не ги видяхме).

    На последно място – да ползваш framework и то OO си има някой отрицателни моменти. На първо място – решаваш проблема със бъговете и straight forward фокусиране върху реалния проблем а не върху програмирането като цяло.. обаче .. ти отваря проблем с производителността – много повече използвана памет (в случаи на огромни сайтове – до 4 mb примерно), както и повече процесорно време за обработка. Започва да се налага нуждата от кеширане на output и други подобни методи. Но това е нищо в сравнение с положителните ефекти… а производителността зависи изцяло от PHP (ако имаш кадърни програмисти разбира се), след 5.3 се очакват доста подобрения, на които аз вярвам (примерно най-ужасният момент на 5.2x версията е бъга с garbage collector-a на PHP и вложени обръщания към обекти.. който ‘уж’ в 5.3 ще бъде решен с patch.

    Това е от мен, надявам се да съм ви бил полезен :)

  10. Viktor Shapilov Says:

    Този коментар е може би най-на място от всичко изписано до момента. Това е истинската идея на Фреймуърковете и наистина е невероятно удобно за фирми и големи екипи от разработчици. Лично аз не долюбвам особено работата в екип, затова и не ползвам фреймуърци а само един пакет със отбрани всичките ми нужни функциии за даден проект, което е в пъти по-бързо и качествено, а и кода остава чист.
    Само едно допълнение ако мога да вмъкна… Освен, че иска по-големи сървърни ресурси, никой посетител не би ползвал някакъв муден сайт който да зарежда 2 дена всяка страница… За това основен фактор е и свързаноста към хоста, но обработката на съдържанието е бавен процес който забавя рендерираното на страниците и освен че иска по-завишени сървърни ресурси дразни и посетителите.

Leave a Reply