LINUX.ORG.RU

Фреймворк для PHP


0

2

Посоветуйте пожалуйста по своему опыту. Требования:

  1. Удобный
  2. Бесплатный
  3. Универсальный
  4. С простой и понятной обучалкой

Лицензия значения не имеет.

★★★★

Последнее исправление: alix (всего исправлений: 1)
Ответ на: комментарий от SOmni

>Всё остальное на джанге будет выглядеть так же, только на питоне, а не на пхп.

Да я вот сам долго думал, потом забил.

Из джанги там ровно два view, в обоих получение данных из БД и вызов render_to_template. Код в шаблоне чуть ли не полностью такой же, как в примере.

KDE41user
()
Ответ на: комментарий от SOmni

>Вся киллер-фича приведённого выше кода, как мне кажется, заключается в этом вот

Вот это, как раз, полная фигня. Ибо вызов модуля (класса, функции) — это элементарное действие для любого фреймворка. Вопрос во взаимодействии и взятии на себя фреймворком рутинных операций. Без потери возможности тонкого управления процессом.

Как сделать вызов модуля из джанговского шаблона я что-то не припомню сходу

Свой тэг назначить.

KRoN73 ★★★★★
()
Ответ на: комментарий от SOmni

>Всё остальное на джанге будет выглядеть так же

что мы упустили? :)

Вот это «остальное» и упустили. Django — это не столько фреймворк, сколько набор библиотек. Почти всё взаимодействие компонентов нужно программировать явно. Это создаёт обычно очень много лишней писанины, сильно замедляет разработку, усложняет модификацию и рефакторинг.

Понятно, что при желании, Django можно допилить до нужного уровня (или, вообще, с нуля реализовать подобную инфраструктуру). Вполне может быть, что мне когда-нибудь (когда заказчики станут не PHP требовать, а Python, например, или когда переход на Python даст столько бонусов, что оправдается переписывание legacy) но если сравнивать именно готовые решения — то Django весьма неоптимален.

Я честно пытался писать на Django пару лет назад, благо, был подходящий случай. Но постоянная забота о мелочах меня доконала и я отложил его до более подходящих времён. В конце концов, «машина должна работать, человек — думать» ;)

И, что характерно, полного кода для реализации задачи на Django в теме так и не появилось. И это тоже показательно.

KRoN73 ★★★★★
()
Ответ на: комментарий от KDE41user

>Код в шаблоне чуть ли не полностью такой же, как в примере.

Ещё бы, если это самая простая часть примера :D

вызов render_to_template

Вот самое хитрое в примере вообще отсутствует — всё взаимодействие компонентов. Ибо это всё на себя берёт фреймворк. Найди в примере вызов рендерера. Нету. Но код — полноценный. Фреймворк — это каркас, связывающий все компоненты библиотек в единое целое и задающий скелет приложения, позволяющий «подвешивать» на себя элементы, не занимаясь вопросами приделывания крючков. А вот в Django об этом постоянно приходится думать.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>Вот это «остальное» и упустили. Django — это не столько фреймворк, сколько набор библиотек. Почти всё взаимодействие компонентов нужно программировать явно. Это создаёт обычно очень много лишней писанины, сильно замедляет разработку, усложняет модификацию и рефакторинг.

Вы, товарищ, ведь тоже не с на «голом пхп» пишете?:) Ваш фреймворк потоще джанги будет, имхо.

anonymous
()
Ответ на: комментарий от KRoN73

>И, что характерно, полного кода для реализации задачи на Django в теме так и не появилось. И это тоже показательно.

Код, кстати, не получится такой, как у тебя, т.к. джанговские templatetags не отдаются по урлу напрямую, надо будет писать однострочную обвязку в виде view, который будет выдавать новости за нужную дату.

Тогда будет дублирование кода внутри view, отдающего js-у содержимое, и внутри темплейт тэга, который выдаётся, по сути, только на главной странице в первый раз (до нажатия кнопки). Впрочем, там всю логику «достать данные за нужную дату» можно вытащить в отдельную функцию, которая будет вызываться и в темплейттэге, и во view.

Но тогда ты скажешь, что это некрасиво и лишняя писанина:)

Более прямым решением, было бы сразу тянуть всё js-ом, выводя на страницу изначально только пустой div. Тогда темплейт тэг станет не нужен. Такое решение пойдёт?:)

anonymous
()
Ответ на: комментарий от anonymous

>Вы, товарищ, ведь тоже не с на «голом пхп» пишете?:)

Ну так и Django — далеко не голый Python :D

Утверждение-то в теме именно так прозвучало, что Django — лучше любого PHP-фреймворка.

Ваш фреймворк потоще джанги будет, имхо.


Безусловно. Вот ещё пример, раз мы про AJAX заговорили.

Задача. Есть класс, генерирующий статическую HTML-страницу (нужно ли напоминать, что под любым nginx или smarty статика порвёт любую динамику, пусть это даже будет JVM-based, в клочья?). Но эту страницу нужно «оживить» для ряда пользователей. Персонализировать, например.

Задача. Сделать статическую страницу, при посещении которой пользователь увидит свой IP-адрес.

Решение на BORS. Опять _полный_ текст. На этот раз для иллюстрации того, что это работоспособный пример, я его закоммитил на трек:

http://trac.balancer.ru/bors-airbase/browser/sites/balancer.ru/classes/balanc...

Работающий пример: http://balancer.ru/tests/bors/demo/jsmod/

Опять 4 файла (контроллер + шаблон на страницу и на модуль) по несколько строк в каждом. Сколько такое же решение займёт на Django? :)

KRoN73 ★★★★★
()
Ответ на: комментарий от anonymous

>Тогда будет дублирование кода

Вот это меня всегда и бесит. В любом фреймворке :) Если приходится дублировать какую-то сущность (не обязательно код) — это указывает на то, что где-то опять программист работает вместо компьютера.

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

Такое решение пойдёт?:)

Не-а. Это будет уже другая задача. Тогда проще всю страницу вообще в динамике отдавать :) Вопрос же был именно в контексте AJAX.

Кстати, это ещё AJAX у меня — «неродной ребёнок», притянутый за уши. Практики применения мало, так что и решения часто неудобные ещё. Например, мне пришлось вручную целый JS-блок описывать. Если пользоваться часто, его генерацию тоже можно автоматизировать :) Вот во втором примере, с динамической заменой, там уже автоматизация, JS писать не приходится.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

В приведённом тобой примере особых преимуществ у борща я не вижу. Я понимаю, что там, наверное, миллион других фич, о которых ты сам знаешь (но мы-то не знаем), и у тебя куча обёрток для своего шаблонизатора, раворачивающихся в 100500 строк на пхп. Конечно, на джанге это просто так не сделать, но сколько лет ты варишь свой борщ? Я, кстати, не говорил, что джанга такая вся крутая, я просто не понял, что за супер-фича показана в твоём коде.

SOmni ★★
()
Ответ на: комментарий от anonymous

>для удобной генерации xml и json модно пользовать

Вопрос об автоматизации этого использования. Обрати внимание, в примере нигде не фигурирует ни XML, ни JSON. Есть только указание, что в данное место статической страницы нужно вставить модуль. И код этого модуля. Всё.

У меня не должна болеть голова о всяких xml, json и прочем. Я не должен заботиться о том, что в каком порядке вызывать.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

> Сколько такое же решение займёт на Django?

ммм... 2 файла? Один - статичный шаблон, второй - питонячий файл для получения и подсовывания ip (ну или каких надо данных).

SOmni ★★
()
Ответ на: комментарий от SOmni

>В приведённом тобой примере особых преимуществ у борща я не вижу.

Вопрос в том, что начальник транспортного цеха так и не выступил :) Примеров на Django в теме я так и не увидел.

и у тебя куча обёрток для своего шаблонизатора

Нет у меня своего шаблонизатора, есть самый часто используемый, Smarty, есть реже используемые чистый PHP (как шаблонизатор, в виде отдельных модулей-шаблонов). Недавно стал на уровне тестов щупать phaml (вариант haml'а). Собственно, я не люблю велосипеды, стараюсь максимально использовать сторонние библиотеки :D

Вот над чем я реально стараюсь работать — это над «структурным клеем», связывающим такие компоненты воедино. То, что заменяет рутинные повторы от проекта к проекту.

но сколько лет ты варишь свой борщ?

Лет 10. Но это уже совсем другая история. Было утверждение, что Django — лучше любого PHP-фреймворка. Если точнее, то что Django — «нормальный человеческий», а под PHP такого нет.

Всё, что я пишу дальше в теме — это ответ на это утверждение. Вопросы срока разработки фреймворка или уровня его обёрток — это совсем другая история. Тогда можно, например, ещё вспомнить вопросы документации, которой у меня нет и т.п. :D

я просто не понял, что за супер-фича показана в твоём коде

Клей. Скрытый от программиста каркас контроллера, который за него делает работу по связыванию компонентов. Благодаря чему при написании новых проектов или расширения имеющихся пропадает огромная часть рутинной работы. Которую я так не люблю :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Ну так и Django — далеко не голый Python :D

Так на голом питоне же вообще веб-приложение не написать, если не реализовывать свой WSGI, или веб-сервер. Ну или cgi, да, но это не в тему:)

Так что сравнивать голый питон с голым пхп в принципе нельзя.

нужно ли напоминать, что под любым nginx или smarty статика порвёт любую динамику, пусть это даже будет JVM-based, в клочья?

А если у нас memcached и уже готовый html там? Память-то не медленнее диска.

Задача. Сделать статическую страницу, при посещении которой пользователь увидит свой IP-адрес.

в urls.py

from django.views.generic import TemplateView

#standart django autogenerated code for urlpatterns
url(r'^page.html$', TemplateView.as_view(template_name='some_page.html'))
#....

В темплейте

Привет, {{ request.META.REMOTE_ADDR }}

Ну и, не вспомню ща, надо вроде requestmiddleware в settings.py подключить.

anonymous
()
Ответ на: комментарий от SOmni

>ммм... 2 файла?

И ты будешь смешивать в кашу питоновский код и HTML? А JS куда? Туда же, в python-файл? :) А вызов AJAX для подсовывания сменного текст вручную будешь прописывать?

Конечно, так обычно и делают. Но это та рутина, которая у меня лично, например, отбивает интерес от программирования на десятом повторе :)

Можно и на голом ассемблере сайты писать. И это будет реально круто! Но зачем? :)

KRoN73 ★★★★★
()
Ответ на: комментарий от anonymous

>А если у нас memcached и уже готовый html там?

Какая разница, если всё равно нужно активировать транслятор?

Память-то не медленнее диска.

Ну так и в nginx часто используемая статика в кеше в оперативке будет :)

в urls.py

Ты сделал _динамику_. Динамическую страницу. В этом случае и у меня будет аналогично :) Разве что не нужно указывать TemplateView.as_view или 'some_page.html'.

Кстати, вот пример рутины. В 99% случаев для простой страницы шаблон можно хранить там же, где файл с кодом, со своим расширением. Зачем указывать имя файла, если оно легко вычисляется? Делаем объект «страница» (bors_page у меня в базовом фреймворке, обычно расширяется до project_name_page со всеми тонкими настройками и конфигами проекта), делаем расширения-контроллеры этого объекта, привязанные к тем или иным урлам — и всё. Фреймворк найдёт этот класс, найдёт соответствующий шаблон, загрузит нужные данные, скормит шаблону, вернёт результат в браузер. Если нужно, опционально закеширует в виде статики и т.п.

Конечно, на это уходит некоторый оверхед. Но тут важно избегать преждевременной оптимизации. Для 99% случаев скорости таких страниц хватит по уши. Чистый оверхед — порядка сотни миллисекунд. Если такие страницы будут дёргаться многими десятками в секунду, это сразу станет видно на мониторе загрузки фреймворка (вся информация — классы, пользователи, количество вызовов, время генерации). Тогда (или если мы заранее делаем быструю страницу) можно уже посидеть и развернуть всю автоматизацию на «ручное управление». Явно указывать все вызовы, все связи. Не хватит этого (а обычно оно и не нужно) — сделаем просто генерацию статики и её персонализацию при надобности через AJAX. Быстрее такого варианта всё равно уже ничего не сделать и на других платформах.

KRoN73 ★★★★★
()
Ответ на: комментарий от anonymous

>А, туплю, нераспарсил исходную задачу

Просто задача очень примитивная, я специально ставлю её в такой форме, чтобы не заморачиваться деталями. Вот, закоммитил сейчас лёгкое украшательство: http://trac.balancer.ru/bors-airbase/changeset/a43ce6be857acb5570f02de89598e5...

Чтобы приветствовало зарегистрированных юзеров по имени, а гостей — с указанием IP, а потом сообразил, что такая мелочь тянет уже за собой заботу об аутентификации, отвлекая от задачи. Ну да ладно, пусть будет так уж :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

> И ты будешь смешивать в кашу питоновский код и HTML? А JS куда? Туда же, в python-файл? :) А вызов AJAX для подсовывания сменного текст вручную будешь прописывать?

Ну за 10-то лет можно на питоне написать то, что за тебя будет JS и AJAX куда надо подсовывать и где надо вызывать :) У тебя же это где-то происходит?

SOmni ★★
()
Ответ на: комментарий от SOmni

>Ну за 10-то лет можно на питоне написать

Я об этом выше и говорил :) Я же нигде не говорю, что Питон плох. Или что Django нельзя допилить напильником.

Вопрос только в утверждении «Попробуйте нормальные человечные фреймворки , Django» :)

В текущем варианте (точнее, таким, каким он был года полтора назад, но не думаю, что что-то сильно изменилось) Django _для меня_ не является _нормальным_ (богатым, насыщенным, удобным) фреймворком. И только :)

У тебя же это где-то происходит?

В фреймворке же :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>Фреймворк — это каркас, связывающий все компоненты библиотек в единое целое и задающий скелет приложения, позволяющий «подвешивать» на себя элементы, не занимаясь вопросами приделывания крючков. А вот в Django об этом постоянно приходится думать.

И ты полез сравнивать теплое с мягким.

Джанга - фреймворк _общего_ назначения. Если туда пихать код-загрузки-хтмл-по-клику-на-кнопку, то она просто утратит целосность. The framework should be consistent at all levels.

Свой фреймворк ты 10 лет писал под себя. Написать нужные _тебе_ библиотеки темплейттагов и прочих врапперов можно и для джанги.

У тебя просто более высокий уровень абстракции. Я могу взять вордпрес и заявить, что все остальное - говно, поскольку на нем сайт можно развернуть за 4 минуты, не написав и строчки кода.

Найди в примере вызов рендерера. Нету.

Тут можно утверждать, что в джанге «Explicit is better than implicit», а у тебя полно магии.

KDE41user
()
Ответ на: комментарий от SOmni

кроме того если речь конкретно о загрузке блока аяком\без аякса, когда чисто джанго функционала (is_xhr или как там) не хватает, выручают пистоны и т.п.

trashymichael ★★★
()
Ответ на: комментарий от SOmni

>Тогда осталось написать простую и понятную обучалку

А вот это уже, не скажу, что невозможное, но с моим интересом к этому вопросу может затянуться не на один год ещё :D

KRoN73 ★★★★★
()
Ответ на: комментарий от KDE41user

>И ты полез сравнивать теплое с мягким

Нифига. Я сказал «докажи» тому, что начал сравнивать теплоту телогрейки и дублёнки :)

Джанга - фреймворк _общего_ назначения.

Я не спорю. Но было сказано, что что он априори «нормальнее» любого фреймворка на PHP. С этим я не согласен.

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

Кэп подсказывает, что Вордпресс — это не фреймворк. На нём нельзя сходу написать кастомную вещь, не похожую ни на что из того, что делалось на нём до этого. На нём нельзя аккуратно присоединиться к уже имеющейся развёрнутой и интенсивно эксплуатируемой системе и понемногу начать переносить её функционал. У меня же это процентов 90 всех моих доходов :D

Тут можно утверждать, что в джанге «Explicit is better than implicit», а у тебя полно магии.

Тебе нужны шашечки или чтобы ехало? Тебе нужно проекты писать или строчки кода? :)

KRoN73 ★★★★★
()
Ответ на: комментарий от trashymichael

>кроме того если речь конкретно о загрузке блока аяком\без аякса, когда чисто джанго функционала (is_xhr или как там) не хватает, выручают пистоны и т.п.

Ну, правильно. Когда мне функционала не хватает, я тоже не ленюсь подключить стороннее решение. Вон, только то, что я обычно с собой таскаю: http://hg.balancer.ru/hgwebdir/bors-third-party/file/ :)

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

KRoN73 ★★★★★
()
Ответ на: комментарий от trashymichael

Вот видишь, ты так даже и не понял о чём речь, хотя уже сколько постингов и с примерами расписал.

Воистину, для не кушавшего мёда нет ничего слаще морковки :D

Ладно, проехали, толку с этого спора не будет.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

я просто не понимаю что в твоем коде есть ТАКОГО чего нет у джанги, и мне лень писать код для каких-то гепотетических примеров что бы доказать что сахар сладкий.

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

>и мне лень писать код для каких-то гепотетических примеров

Что и требовалось доказать. Писать код на Django — слишком лениво. Рутина отнимает много времени и утомляет. Об это я и писал выше пару раз.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

ок, ты меня убедил, я создаю папку и делаю django-admin startproject...

* небольшой дисклаймер, дальше много быдлокода, плохих практик етц етсетера *

задаю минимальные настроечки:

база sqlite3 (дописываю одно слово «sqlite3» в значении ENGINE базы данных по умолчанию)

каталог с шаблонами (можно было обойтись, ладно, задам «/blah/blah/templates/»)

создаю приложение news (manage.py startapp news)

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


from django.db import models

from datetime import datetime, timedelta

class NewsManager(models.Manager):

    def get_yesterday_news(self):

        return self.get_query_set().filter(created_on__range = (datetime.now() - timedelta(days = 2), datetime.now() - timedelta(days = 1)))

    def get_today_news(self):

        return self.get_query_set().filter(created_on__gt = datetime.now() - timedelta(days = 1))

class News(models.Model):

    slug = models.SlugField()

    created_on = models.DateTimeField(auto_now_add = True)

    objects = NewsManager()
    

добавляю новостям теги шаблонов (cd news, mkdir templatetags, cd templatetags, touch __init__.py, touch news_tag.py)

реализую тег


from django.template import Library

register = Library()

from news.models import News

@register.inclusion_tag("news-block.html")

def news():

    return {"object_list": News.objects.get_today_news()}

* дальше вообще ХАРД БЫДЛОКОД *

описываю роуты, для простоты все определяем в urls.py проекта


from django.conf.urls.defaults import *

from news.models import News

urlpatterns = patterns('',
    url(r"^previous_news/$", "django.views.generic.list_detail.object_list", {"template_name": "news-block.html", "queryset": News.objects.get_yesterday_news()}),
    url(r"^$", "django.views.generic.simple.direct_to_template", {"template": "index.html"}),
)

добавляю «news» к INSTALED_APPS в settings.py

создаю шаблоны

index.html



<head>

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>

    <script type="text/javascript">

    (function ($, window, undefined) {

        $(function () {

            $("#more-news").click(function () {

                $("#news").load("/previous_news/")

                return false

            })

        })

    })(jQuery, window)

    </script>

</head>

<body>

{% load news_tag %}

{% news %}

<a href="#" id="more-news">more</a>

</body>

news-block.html


<div id="news">

    {% for object in object_list %}

        {{ object.slug }} <br />

    {% endfor %}

</div>

почти конец, manage.py syncdb, manage.py runserver

ЗЫ джанго никого ни в чем не ограничивает, что не нравится можно выкинуть, чего не хватает можно доделать и переделать, для джанги есть куча хороших готовых решений, и я не говорю про пинакс и т.п.

ЗЫЗЫ с джанго давненько не работал, если че с датами там наплутил не обессудь, быдлокод же

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

Спасибо. А то я уже 2 раза порывался написать =)

pi11 ★★★★★
()
Ответ на: комментарий от anonymous

пишу же, с некоторого времени не практикую django когда они появились меня тоже заинтересовало, но пацаны сказали что это больше для внутренней реализации тех же generic views'ов, которые никуда убирать не собирались, потому зачем?

trashymichael ★★★
()
Ответ на: комментарий от trashymichael

>пишу же, с некоторого времени не практикую django когда они появились меня тоже заинтересовало, но пацаны сказали что это больше для внутренней реализации тех же generic views'ов, которые никуда убирать не собирались, потому зачем?

Они, по правде, очень хороши, если вкурить (это имхо, если что). С ними удобно писать универсальный код, который мигрирует из проекта в проект.

Функции, если делать их универсальными, либо обрастают десятком передаваемых аргументов (классические generic views уже страдают этим), либо не получаются универсальными и удобными.

Кроме того, внутри класса можно «передавать» переменные между методами через self. Плюс mixin-ы, например для разного типа отдаваемого контента.

Я вот сначала к этим вьюсам сомнительно относился, а потом получилось так, что в проектах не осталось ни одной чистой функции - всё через классы. Хоть ООП я не так и сильно люблю.

Из недостатков могу отметить, что без вглядывания в исходники джанги не понять, как конкретно надо что-то переопределять при наследовании. Документация не помогает.

anonymous
()

Фреймворки для php не нужны. Если только начинаешь, то писать всё надо самому -> будут свои наработки -> можешь использовать в следующих проектах -> чужие поделия не нужны. Я прав.

Lynyrd
()
Ответ на: комментарий от anonymous

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

trashymichael ★★★
()

Я бы не трогал (в пределах возможного) готовые фреймворки, пока не научился бы их писать самостоятельно.

А так я работал с Zend и Yii, первый может быть и полнее второго, но весит в 8 раз больше и довольно старый (что, может быть и плюс). С Yii работать в разы приятнее.

Mironor
()
Ответ на: комментарий от trashymichael

ведь эта разница на лицо даже если сравнивать джангу и борщ, например, как бы там ни было, на джанге проект возьмет любой вася (знающий джанго) и продолжит работу, а с борщом ему сначала нужно будет КОВЫРЯТЬ

trashymichael ★★★
()
Ответ на: комментарий от KRoN73

решения часто неудобные ещё

Вот очень удобное решение. php-jquery.

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

Hertz ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.