Ответы пользователя по тегу PHP
  • Стоит ли использовать ооп?

    Тостер, ну почему ты не сохраняешь где-нибудь в local storage сообщения, которые не дописаны? Ааааа! В общем, написал, закрыл вкладку, пишу снова.

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

    Понятие алгоритма (машина Тьюринга) императивно. Первые архитектуры компьютера, описывающие как хранить код и данные (архитектура фон Неймана и т.п.), тоже императивные. Императивно/дискретно работает "физический мир полупроводниковой логики". Императивная парадигма является "родной" для компьютера. А ООП - это продолжение, эволюция императивной парадигмы.

    Императивная программа состоит из инструкций, которые что-то меняют в памяти. Если смотреть с минимальным зумом, то много инструкций - это функция. А много функций - это модуль. С точки зрения инженерии ПО важно программе быть максимально модульной, максимально DRY, легко изменяемой, эффективно решающей задачи поставленные и еще много чего. Так вот, кажется, у нас все есть, растащил по директориям кучу файлов, функции/модули/область видимости, но этого не хватит, ведь есть же еще типы, а их надо передавать туда-сюда, обрабатывать. Есть алгоритмы, которым глубоко фиолетово, что обрабатывать, будь то массив, словарь, список, дерево или даже генератор (люблю питон @ пиарю где могу). Кстати говоря, тут можно задуматься о сути итераторов, но это оффтопик.

    Во времена популярности ассемблера типов "еще не было". И это вызывало проблемы: множество рутины, множество кода, возможность прострелить себе регистр и так далее. Во времена C были примитивные типы и даже структуры, которые могли хранить данные и указатели на данные. Но все еще как-то неудобно, множество низкоуровневых действий. Нет даже строк, представлять их в виде массива - не слишком удобно, гораздо лучше иметь что-то вроде черного ящика. Где-то в те же времена уже было ясно, что нужно иметь еще более абстрактные типы, которые могут хранить контекст, иметь свои функции (методы), инициализироваться, деинициализироваться. В общем, нужно создавать типы "высокой абстракции", а еще уметь их модифицировать, расширять, комбинировать. И лучше еще с памятью явно не работать. А еще чуть позже популяризовались языки с динамической типизацией, где стало можно не заботиться о типах совсем. Мне даже кажется, что тут уместно сказать, что типов будто "уже не стало". Все есть контейнеры со своей областью видимости. Правда, все это медленно, особенно, если учесть, что динамическая типизация очень любит интерпретацию или динамическую компиляцию. Чем выше уровень, тем все тормознее.

    На самом деле все эти идеи были очень давно (ООП, динамическая типизация), еще даже раньше, чем появился C, однако людям было нужно время, чтобы осознать, обкатать.

    С ООП теперь все удобно. Кроме модулей и функций есть сложные типы (классы), которые можно свободно создавать, наследовать, регулировать область видимости, заменять методы, использовать интерфейсы, "строить модули внутри модулей", не использовать глобальные переменные, внедрять зависимости, не дублировать код. В языках, реализующих неклассическое ООП, существует еще больше свободы. Можно использовать миксины направо-налево, классы являются объектами, а где-то и классов нет, потому что есть объект и с ним и так все хорошо))

    Это все особо важно и нужно в прикладных задачах, где обрабатываются разные данные, выводятся в разных видах или где есть интерфейс пользователя с множеством однотипных элементов. Практически всегда там возникает ситуация, когда нужно определить множество похожих объектов, сделать удобное API, использовать и расширять стороннюю библиотеку. Кроме того, существует множество паттернов, которые можно переносить откуда угодно куда угодно, не думая при этом. В вебе, с учетом того, что 95% приложений крутятся вокруг MVC и его вариаций, ООП очень даже кстати: модельки - это однотипные объекты из однотипных полей, имеющие в себе какую-то логику (свои функции/методы), контроллеры - однотипные объекты (получение данных/параметров запроса, выдача необходимого ответа в нужном виде). Если взять любой фреймворк, то там реализовано множество модулей, которые что-то реализуют: ORM, роутинг, кэш, сессии, request-объекты, response-объекты, какие-нибудь карты сайта, админки, модельки для юзеров, что-нибудь для работы со статикой, формы, локализация... Если нужно что-то расширить, то достаточно посмотреть на API, отнаследоваться, реализовать/заменить метод.

    Наверное, нужны какие-то примеры. Вот представьте, что пишете простой сайт, который должен отдавать готовый HTML. Но кроме этого сайт модный, поэтому он полностью ajax (html5 history api), никаких перезагрузок, только первая загрузка страницы, которая выгружает и фронт и стили и отрендеренную страничку, а потом дергаются нужные данные для других страниц (в json, туда кладется отрендеренная часть и еще какие-нибудь важные данные) с бэкенда. Оговорюсь, что это не SPA, а именно full ajax сайт, который все-таки еще рендерится на сервере в каком-нибудь серверном фреймворке. И ваш бэкенд должен отдавать, соответственно, 2 варианта страниц: обычную (как при прямом заходе по ссылке, это и для пользователя и для бота) и json-вариант для других страниц (это уже только для пользователя, соответственно). Вы создаете крутой контроллер, который в зависимости от параметров в GET, либо в зависимости от заголовка рендерит то json, то html. А дальше наследуетесь от этого контроллера и совсем не заботитесь о том, что у вас отдает конкретный контроллер: переопределяете метод с контекстом и отдаете в нем нужные данные, а уж что с ними станет в шаблоне или как их обработает фронтенд, получив из json, - без разницы. Нужно сделать только ajax-контроллер? У вас для него есть класс, осталось опять же только отнаследоваться. Нужно отдавать SEO-заголовки? Можно сделать миксин для контроллера и миксин для модельки и снова переопределить только один метод а-ля get_meta_title и все. Ну, понятное дело, я тут упустил мелкие подробности и все это актуально больше для языка вроде python и подобных (уж на чем пишу), но вот пример ООП-задач.

    Или у вас есть либа... Допустим, она зависит еще от трех других либ, плюс предоставляет какое-то API. Выглядит в виде класса, в нем несколько методов, пара публичных, + конструктор, + свойства. Пишете тесты, подменили зависимости объектами-пустышками и все получилось красиво. А как это сделать, использовать ли там какие-то специальные контейнеры или прямо на лету пропатчили класс (̶̶к̶а̶к̶,̶ ̶н̶а̶п̶р̶и̶м̶е̶р̶,̶ ̶м̶о̶ж̶е̶т̶ ̶п̶и̶т̶о̶н̶,̶ ̶п̶о̶т̶о̶м̶у̶ ̶ч̶т̶о̶ ̶о̶н̶ ̶в̶а̶м̶ ̶т̶а̶м̶ ̶н̶е̶ ̶"̶п̶а̶б̶л̶и̶к̶ ̶с̶т̶а̶т̶и̶к̶ ̶в̶о̶й̶д̶ ̶в̶с̶е̶ ̶м̶н̶о̶г̶о̶с̶л̶о̶в̶н̶о̶е̶ ̶и̶ ̶т̶о̶л̶с̶т̶о̶е̶ ̶г̶д̶е̶ ̶м̶и̶н̶и̶м̶а̶л̶и̶з̶м̶"̶), не суть.

    Да вот даже возвращаясь к тем итераторам, что я выше затронул. Допустим, есть у вас итератор и нужно сделать его thread safe. То есть при вызове метода, который возвращает следующий элемент, вы должны захватить мьютекс, а потом его отдать. Это легко можно сделать с помощью наследования: просто наследовавшись и обернув нужные методы. Либо с помощью интерфейсов, чтобы было универсально и для каких угодно объектов: реализуется интерфейс итератора в виде класса, который принимает другой итератор и его оборачивает.

    Вообще, примеров очень много, они повсюду, особенно, в вебе. Если в таких прикладных задачах не использовать ООП, то я даже не представляю, как тестировать этот код. Как его поддерживать, меняя логику? А как менять компоненты? Как быть DRY? Тут я, кстати, вспомнил про то, что вот, например, есть в C структуры. Это что-то вроде урезанного класса и на самом деле можно реализовать многие штуки с ними, писать отличный код, но он просто будет сложнее в поддержке и по скорости разработки будет очень далеко позади. Ядро линухи выглядит очень красиво и совсем там не лапша. Однажды фиксил драйвер, чтобы заработал 5ггц вай-фай, так вот он был красив и строг внутри. Кстати, в Go классы реализованы в виде структур, но я не смогу подробнее рассказать об этом, т.к. не смотрел этот язык. ООП - это не какая-то супер фича, а это всего лишь подход. Языки же добавляют синтаксический сахар, реализуют классическое ООП (java/c#/c++/etc) или же неклассическое (python, js, etc).

    Кроме ООП-парадигмы и процедурной парадигмы есть еще, например, функциональная. Но это отдельная совсем тема. В мультипарадигменных языках можно писать по-разному. Если что-то удобно представляется в виде цепочки функций, выглядит так, как будто нет побочного эффекта или его легко изолировать, то нет стоит городить классы или процедурный ад. Тем более в языках, которые близки к ФП, обычно полно встроенных функций, можно объявлять анонимные функции, почему бы этим не пользоваться. Ну или, например, у вас получился какой-то модуль, в котором не нужна ни инициализация, ни контекст ему не нужен, все выглядит как просто 4 связанные функции, то зачем здесь нужно ООП? Хотя если что-то из этого можно кастомизировать, а вы чувствуете, что это понадобится, т.к. есть объекты, которые будут расширять функциональность, то стоит задуматься. Главное не оверинжинирить.
    Ответ написан
    4 комментария
  • Вывод pdf из MySQL?

    Как принятно на русских ресурсах не отвечать на вопрос, а давай советы :) Но в этот раз совет важный и даже юзабельный.

    Хранить файл в БД - плохо. Может показаться, что это удобно (например, только бэкап БД спасет всех).

    Но на самом деле:
    • Растет размер БД. Что делать, если он станет запредельным из-за сохраненных там файлов?
    • Возрастает нагрузка на диски/оперативную память сервера БД.
    • Офигенно растут логи, а это дополнительная нагрузка на диск.
    • Замедлится передача данных от MySQL, т.к. там, во-первых, может быть сеть со своей пропускной способностью, а во-вторых, MySQL будет передавать большой файл маленькими частями (снова оверхед на I/O диска и сети).
    • То, что можно отдать обычным nginx'ом как статику, отдается через костыли.

    Хранить блобы можно, конечно, но рано или поздно сделаете БД узким местом. Если и хранить блобы, то очень-очень маленькие, но и даже это спорно и зависит от задачи.

    Поэтому отказывайтесь от идеи.

    Просто в этих пдфках содержаться персональные данные пользователей и нельзя чтобы они имели прямые ссылки(доступ к ним открывается только после авторизации)

    Причем здесь БД? Храните файл в том месте, которое не сервится наружу. А доступ до файла регулируйте при запросе. То есть у вас есть какой-то url для файла, там содержится его id, например. Вы проводите авторизацию: если можно забрать файл, спрашиваете у БД ссылку, где он находится на диске (а это место наружу не видно), и отдаете файл подобным образом, как делаете сейчас. НО, если ожидаются крупные файлы, читать файл нужно по частям, иначе можете закончить оперативу. В фреймворках обычно есть для этого инструменты, кстати.
    Ответ написан
    3 комментария
  • Можно ли использовать VPN только для определенных запросов с сервера на сервер?

    Если к API нужно ходить с фронтенда, то можно на вашем nginx запроксировать запросы на сторонний ресурс. В ряде случаев понадобится настройка чего-нибудь (nginx/php) на удаленной стороне (если, например, нужно передавать хидеры специализированные, например http-x-real-ip). Ситуация вполне штатная, обычная. Если нужно ходить с бэкенда, то так и напрямую ходите (curl или что там у вас). Ситуация тоже обычная.

    Но я так понимаю, что главный вопрос в том, не плохо ли тут использовать vpn? Здесь нужно знать, какой у вас vpn. Самый печальный vpn - это pptp, т.к. небезопасен и будет дольше реконнектиться в случае потери соединения (да и в сравнении, например, с openvpn он даже в конфигурировании неудобен). Уверен, что у вас не pptp, это просто к слову (никто в здравом уме не будет поднимать pptp между сервер-сервер). Грубо говоря, все остальное (openvpn, ipsec и т.п.) можно использовать: проверено временем, стабильно. Касательно оверхеда: в 99% некритично. Например, если это openvpn l3 по udp, то оверхед на каждый пакет по размеру будет ~70 байт (где-то 20 ip, 8 udp, порядка 40-50 на tls)... примерно. И хотя если посчитать этот размер относительно маленьких пакетов, может выйти больше самого пакета (смотря как считать еще), это ни о чем не говорит: при достаточном канале (а у вас, раз речь идет про сервера, должно быть все хорошо) это некритично. В плане времени сколько-то уйдет на шифрование, но опять же для api это некритично (и надо учитывать, что соединение-то постоянное, то есть временной оверхед, например, на tcp/http и тем более https выше, а оно повсеместно, никто не парится). Для собственного успокоения можете замерить ширину канала (nc), потыкать в api (hping).

    Кстати, если везде линуха, не нужна защита, нет по пути страшных фаерволов, видимость на уровне l3 есть, то лучший вариант, как по мне, - это линуксовый ipip, либо gre: минимальный оверхед, крайне легко настраивается (описано в lartc), не нужно дополнительное ПО. Не знаю, насколько это популярно, но я бы использовал такой "vpn", если возможно/нужно.

    Еще важно убедиться, что vpn поднимается при ребуте сервера, что работает реконнект в случае чего. Собственно, это относится ко всем сервисам вообще.

    В качестве вывода: никаких проблем, используйте.
    Ответ написан
    1 комментарий
  • Как с помощью php получить список включенных модулей Apache?

    Список всех включенных модулей можно узнать с помощью apachectl.

    apachectl -M

    Напишите обертку вокруг этого.

    Либо если используется mod_php, то есть функция apache_get_modules() в PHP.
    Ответ написан
  • Как правильно реализовать поиск на ajax?

    Я бы все переделал в таком случае: для поиска нужно сделать отдельную страницу, настоящую, формируемую на бэкенде, с URL вида http://.../search/запрос/, например. И по ajax обращаться, например, на http://.../search/запрос/?json=1 (это все GET, никаких POST для этой задачи) и получать там объект, который рендерить на клиенте (потребуется шаблонизатор, ибо без него некрасиво), либо получать часть страницы, уже сформированную, которую просто $(...).html(...). Этот же подход можно использовать для любых страниц, которые надо по-настоящему отдавать (поисковым ботам, прямым заходам), но при этом быстро все грузить без обновления страницы.

    Либо же при заходе на страницу брать location.search и делать запрос, но это менее некрасивый вариант.

    Посоветовал бы еще почитать про фрейворки-библиотеки что на клиенте, что на сервере, ибо mysql_fetch_assoc и history.pushState в коллбеке в 21 веке - это жесть. :)
    Ответ написан
    2 комментария
  • Клон сайта и оценка посещаемости. Как реализовать?

    Техническая сторона: squid/nginx - это "не те прокси", так скажем, никаким боком к данной задаче не подходят. Нужно снять статистику (то есть поставить скрипты на страницу), поэтому iframe не работает, нужен полноценный сайт. Тянуть данные на фронтенде нельзя по этой причине, ну и сама разработка будет тяжела: нужно будет верстать что-то, действительно разрабатывать сайт. Единственный вариант вижу: на бэкенде получать запрос, спрашивать по нему оригинальный сайт, получать контент, встраивать свои скрипты, отдавать. Выглядит это просто и должно сработать.

    Трафик: чтобы протестить, нужно привлечь реальный трафик, а как только начнете привлекать, попадете в бан у поисковых систем, кроме того подпортите продвижение у оригинального сайта, из-за чего еще и на санкции от его владельцев нарветесь. Кроме того, тот же трафик на свой сайт не получите. Можно сказать, этот пункт не выполним. А даже если был бы выполним, все равно не добьетесь правильной статистики, так как время на сайте, конверсия, глубина просмотров, посещения и т.п. - это комплексные показатели. У двух сайтов, продающих одно и то же, они могут кардинально отличаться. Недавно я делал новый сайт-каталог, владельцы решили отказаться от старого сайта, потому что его было невозможно поддерживать и дорабатывать, нужен был редизайн и т.п. В итоге у них посещения упали процентов на 15-20% (реструктуризация, хотя ссылки максимально сохраняли), но при этом глубина просмотров и время на сайте возросли значительно. Эти показатели зависят, скорее, от вашего подхода, качества контента, а не от того, что продается. Кроме того, рентабельность не зависит от этих показателей напрямую. Да, может быть очень много посещений и просмотров, даже глубина просмотров может быть неплохая и время нахождения на сайте тоже, но конверсия будет низка, потому что все как-то криво и бездушно на сайте.

    Моральная оценка вашей "идеи": плохо, очень плохо. Такие методы плохи, а ресурсы, созданные таким образом, не выстрелят.
    Ответ написан
    Комментировать
  • Nginx + php5-fpm VS Nginx + Apache; Что выбрать?

    Сильно ли выигрывает в производительности Nginx + php5-fpm ?

    У них разная архитектура: nginx может обслужить большее количество запросов в единицу времени с меньшим расходом памяти. Так что в теории должно быть: да, сильно.

    Можно ли прикрутить .htaccess Nginx + php5-fpm ?

    Можно сделать все то, что умеет .htaccess в конфиге nginx, но прикрутить нельзя.

    Стоит ли переходить на Nginx + php5-fpm ?
    Сейчас стоит nginx+apache на виртуалках на выделенном сервер. Все на Centos + openvz.
    Проектов много разных крутится.

    А зачем? Если задаете такие вопросы, у вас сейчас все хорошо.

    Схема с nginx красивее, легковеснее, проще в настройке. Я несколько лет уже использую nginx+gunicorn (это питоновый wsgi-сервер, прослойка между приложением и веб-сервером), никакой нужды нет в apache. Но если все ОК, переходить не нужно. Также если нужно будет работать с типовыми проектами, которым нужен .htaccess, но писали не вы, это будет печально: я постоянно плачу кровавыми слезами, если подобная задача возникает, т.к. нужно переписывать все эти .htaccess.
    Ответ написан
    Комментировать
  • Какое использовать регулярное выражения для поиска и замены url?

    Используйте вот эту штуку.
    Ответ написан
    Комментировать