LINUX.ORG.RU
ФорумTalks

Почему web так убог?

 , ,


1

2

Собственно давно задавался этим вопросом. Я сам последнее время работаю с вэбом и почти каждый день спрашиваю себя - почему здесь всё настолько криво. Почему спросил сейчас? Вот сижу и пишу стопяцотый велосипед который сделает удобным вывод форм на страничку избавив от всего этого хлама типа select, textarea, checkbox(value) и прочего сказочного поноса. Конечно пишу на пыхе потому что целевой фреймворк, как и подавляющее большинство, на пыхе. И тут вот такая тема - Python или PHP, или вообще Pascal?

Невольно задаешься вопросом, почему все эти люди которые создали всякие html, php, css и прочие js (возможно к последнему притензии мои и зря), смогли вывести это в мэйнстрим? Почему мэйнстримом де-факто стали настолько убогие и кривые стандарты и технологии?

P.S.
Мнения тех, кто считает что все нормально и не видит глобального ада, не очень интересно. Интересно именно чем думали создатели этого.

★★★★★

Ответ на: комментарий от TDrive

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

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

полная каша

А в php бывает иначе?

Конечно. На [почти?] любом языке можно писать структурно. И на любом языке можно писать write-only.

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

Ну давай расскажи как по другому добавить метки на карту... в JSON вторым запросом забрать? И кому нужен этот огород?

Вариант с JSON-метками будет компактнее. Особенно, если потом потребуется динамика.

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

Это костыль, вызыванный отсутствием в CSS элементарного даже не языка, а хотя бы препроцессора.

css - клиент сайд, scss - сервер сайд.

Ты думаешь, что чем-то опроверг утверждение, что CSS препроцессоры — костыль для CSS, поскольку тот дубовый и не умеет ни констант, ни вложенности правил?

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

Ок. Может тогда вообще откажемся от генерации на сервере? Отправим клиенту шаблон и все данные будем уже вхерачивать в него js'ом

Сейчас, когда клиентские машины стали достаточно мощными, это вполне оправданный подход.

Ну и что, что сайт еле шевелится на 4 котлах с 16Гб оперативы.

При столь криворуком программировании точно также сперва ещё и сервер с 24 котлами и 48Гб оперативы ляжет на такой задаче.

Ты как-то вольно в рамках одной задачи ставишь квалифицированных программистов на server-side и быдлокодеров на client-side. Используй равную квалификацию.

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

А конкретно вот этим говном:

Очень правильно сказал.

Я вижу что это говно, но не знаю как его улучшить.

ctrl+A, Del.

То что ты пилишь называется хелперы, но хелперы обычно используются для расширения стандартного функционала html, Например для добавления в форму вариантов html запроса PUT, DELETE... в виде отдельных инпутов для поддержки всеми браузерами или для добавления ключа для защиты от xss (или как там). То есть формируется какойто набор требований к форме и чтобы его каждый раз не реализовывать пишут хелпер для гнерации форм. В твоем же случае то что ты пишешь совершенно бесполезно и не обрабатывает все возможные варианты форм, например не задать элементам id.

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

#define работает, милейший. Костыли, написанные через задницу, тоже работают. Либо ты пишешь только hello world'ы :)

Ну вообще-то приличные люди так и делают :)

xD

сообщения шли подряд. очень мило получилось.

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

Не переменные — константы. Циклов таки не будет :}

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

elseif и switch — это семантически разные конструкции, и хотя switch можно сделать на elseif (но не elseif на switch в общем случае), логики их применения разная.

Но в принципе же можно реализовать? А там где тебе не хватит switch сделай вложенные if. Я вообще не против elseif и сам юзаю. Но когда попадается 96 esleif подряд вида elseif ($_SERVER['REQUEST_URI'] == '/catalog/xxx/yyyyyy') хочется кого-нибудь убить. Впрочем они же это и со swith бы написали...

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

elseif ($_SERVER['REQUEST_URI'] == '/catalog/xxx/yyyyyy')

Майнготт. А разобрать REQUEST_URI на смысловые части, завести их в хэш, в качестве ключей - функции-обработчики? Или в пыхе так не модно?

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

Откуда ж мне знать, что ты имел в виду. И вообще, с ЛОРа не уходят, в том числе из тредов :}

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

А что, настройки кэширования уже перестали передаваться в HTTP заголовках?

Где они там передаются, на вскидку помню только настройки времени кукисов а так обычно клиент ломится на сервер получая в ответ 304.

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

Не, это слишком просто. Лучше придумаем ещё один способ расположения блоков :)

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

Ты наверное пропустил сообщение где я говорил, что я как раз очередное такое разделение и пилю

Ну так откуда столько ненависти, если ты его пилишь один раз и на годы вперёд?

Я вижу что это говно, но не знаю как его улучшить.

1. Декомпозиция 2. Декомпозиция 3. Декомпозиция

Считай каждый генерируемый элемент отдельной сущностью. Это позволит в дальнейшем очень легко расширять и поддерживать систему. Лучше — ООП, так ты максимально абстрагируешься от сайд-эффектов в будущем, когда уже забудешь, что у тебя там за что держится.

Я лет 7 назад, кстати, слепил подобный код (хотя и с меньшим объёмом посторонней обработки), до сих пор его по-немногу переписываю, как дело доходит до модификаций. Хорошо ещё, что API сразу довольно строго формализовал, так что внутренние переделки не сказываются на сотнях тысяч строк имеющегося уже кода.

Сейчас, если выкинуть наследие прошлого, то скелет выглядит примерно так:

               switch($edit_type)
                {
                    case 'checkbox_list':
                        $html .= $this->element_html('checkbox_list', $data);
                        break;

                    case 'string':
                    case 'input':
                    case 'int':
                    case 'uint':
                    case 'float':
                        $html .= $this->element_html('input', $data);
                        break;
                    case 'hidden':
                        $html .= $this->element_html('hidden', $data);
                        break;
// ...
                   case 'timestamp_date_droppable':
                        $data['name'] = popval($data, 'property');
                        set_def($data, 'can_drop', true);
                        if(!empty($data['args']))
                            $data = array_merge($data, $data['args']);
                        if(popval($data, 'subtype') == 'simple')
                            $html .= $this->element_html('date_simple', $data);
                        else
                            $html .= $this->element_html('date', $data);
                        break;
// ...

    function element_html($element_name, $params = array())
    {
        $element_name = 'bors_forms_'.$element_name;
        $element = new $element_name;
        $element->set_params($params);
        $element->set_form($this);
        return $element->html();
    }

Ну и, соответственно, генераторы. Вот тут уже пресловутый HTML в грязном виде:

<?php

class bors_forms_hidden extends bors_forms_element
{
    function html()
    {
        $params = $this->params();

        extract($params);

        $value = $this->value();

        return "<input type=\"hidden\" name=\"$name\" value=\"".htmlspecialchars($value)."\" />\n";
    }
}

или уже страшные монстры с кучей параметров отображения:

<?php

class bors_forms_checkbox extends bors_forms_element
{
    function html()
    {
        $params = $this->params();

        if(!empty($params['property']))
            $params['name'] = $params['property'];

        $form = $this->form();

        extract($params);

        $checked = $this->value('checked');

        if($checked)
            $checked = "checked";

        $form->append_attr('checkboxes', $name);

        if(empty($value))
            $value = 1;

        $html = "";

        // Если указано, то это заголовок строки таблицы: <tr><th>{$th}</th><td>...code...</td></tr>
        if($th = defval($params, 'th'))
            $html .= "<tr><th>{$th}</th><td>";

        if(!empty($label_css_class))
            $label_css_class = " class=\"$label_css_class\"";
        else
            $label_css_class = "";

        if($label)
            $html .= "<label{$label_css_class}>";

        $html .= "<input type=\"checkbox\"";

        foreach(explode(' ', 'checked name size style value') as $p)
            if(!empty($$p))
                $html .= " $p=\"{$$p}\"";

        $html .= " />";

        if(empty($delim))
            $delim = '&nbsp;';

        if(empty($br))
            $br = "<br/>\n";

        if($label)
            $html .= "{$delim}{$label}</label>{$br}";

        if($th)
            $html .=  "</td></tr>\n";

        $html .= "\n";

        return $html;
    }
}

Самый же толстый по размеру — класс bors_forms_date, там тонна вариантов времени, на 4.5 кб кода. У меня фреймворк понимает timestamp, нечёткую дату в виде int'ов и строк, всё это выводится в вариантах с произвольной формой, в виде выпадушек год/месяц/дата и т.п. Параметров получается вагон. Сейчас стал растаскивать по отдельным классам (типа, просто дата текстовой строкой — bors_forms_date_simple и т.д.), но legacy требует поддерживать и этот класс.

А, ведь, учил меня Лео Броуди в Thinking Forth, что нужно избегать (перефразируя в наши термины) «умных» классов и методов. Если две сущности похожи и отличаются в деталях, не нужно писать одну сущность и всовывать внутрь кучу проверок, надо писать общую для них третью сущность, надстраивать над ней две наших (чтобы не дублировать код) и пользоваться ими по отдельности.

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

Например.

Generation of Expires and Cache-Control HTTP headers according to user-specified criteria

This module controls the setting of the Expires HTTP header and the max-age directive of the Cache-Control HTTP header in server responses. The expiration date can set to be relative to either the time the source file was last modified, or to the time of the client access.

These HTTP headers are an instruction to the client about the document's validity and persistence. If cached, the document may be fetched from the cache rather than from the source until this time has passed. After that, the cache copy is considered «expired» and invalid, and a new copy must be obtained from the source.

http://httpd.apache.org/docs/2.2/mod/mod_expires.html

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

Это перл-программист должен быть ленив. А php-программист должен быть трудолюбив!

С моей точки зрения Perl и PHP — близнецы братья. Perl чуть более гибок и чуть более W/O. PHP несколько строже семантически, но с болячками времён «HTML-шаблонизатора».

Довольно близок к ним Ruby. Чуть дальше отстоит Python. Но подходы к программированию на любом из них практически идентичны. Даже в сравнении с Java или Си, не говоря уже о Forth или Lisp :)

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

Ерунды сказал ты. Во-первых $tAttrs там не просто для красоты, он откуда-то взялся, верно? Так что id очень легко задается. Во-вторых id это отдельный ад. Эта штука генерит форму, где гарантия что форма на странице одна? Может это обратный звонок который есть в шапке и на странице обратного звонка с этой же шапкой, да мало ли? И что ты будешь делать с неуникальным id? Id это почти всегда плохо потому что тебе нужен единый пул id чтобы не дублировать их и механизм работы с этим пулом. А в форме это еще и не нужно, так как у каждого элемента ввода таки есть name (смотри-ка, а мне доказывали что сущности-то таки разные, а оказывается у них у всех есть общее свойство характерное только для них...) и он уникальный. Ну и наконец в том конкретном применении которое я делаю прямо сейчас, я использую id. И в заключении - это таки шаблонный хелпер который идет в дополнение к обработчику форм и вообще вынесен в отдельный класс. Правда класс подгружается именно обработчиком.

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

Так БЕСИТ же! :)

Ну, чёрт его знает, где грань проходит. Раздражать что-то меня в программировании, порой, раздражает. Но до бешенства никогда не доводит. Если что-то начинает раздражать сильно, надо думать, что ты делаешь не так. Или подход менять надо, или, вообще, инструмент. Когда меня невысокая скорость PHP начинает раздражать, я достаю Java, если раздражают ограничения CSS, то достаю LESS и т.д.

Вот действия конкретных людей и компаний — да, легко могут бесить. Уже почти недель, как бешусь на Google AdSense :) Точнее на их идиотскую политику одностороннего общения с клиентом. Но и тут моё бешенство не особенно продуктивно. Потому что пара вариантов обходного решения проблемы нашлась именно когда я перестал беситься :)

Не зря, наверное, древний сказал: «ты сердишься — значит, ты не прав».

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

Ты не поверишь, но это сделано на платформе у которой в движке это все разобралось и подключились специальные поля и из базы выдернуты специальные значения для keywords (а именно они там дальше и дефайнятся) еще на стадии роутинга (преобразования ЧПУ в смысле) и их можно достать и вывесит одним методом.

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

Сложно смириться с несовершенством мира, тем более рукотворного (^. ^)

Именно поэтому в программировании ненависть мало уместна. В отличие от реального мира там нам очень многое подвластно. И несовершенство программного мира поправить/обойти намного проще, чем в реале :)

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

И меня ещё спрашивают, почему я считаю что весь код на php выглядит как говно. Потому что он выглядит как говно!

Xellos ★★★★★
()

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

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

Ну и что нового? У меня этот кусок кода как раз из чего-то вроде того же, но вызывается это у меня как $this->getFieldHtml($arData); Чем моё говно говённее? Тем что матрешка тоньше?

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

Иллюзия контроля - одно из распространённых когнитивных искажений. На самом деле сложные системы развиваются (или правильно будет сказать: эволюционируют) по своим собственным законам и плевали они на программиста с его хотелками.

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

А что, настройки кэширования уже перестали передаваться в HTTP заголовках?

О! Помню, как злился по этому поводу :D В Хроме очень хитрое и вольное отношение к кешированию (по крайней мере было в прошлом году). Однажды я дня три играл с параметрами и стандартами, пытаясь запретить ему кешировать статический HTML. Вагон и маленькую тележку стандартных методов он тупо игнорировал. Но в итоге подобрал, засунул в свою стандартную функцию template_nocache() (тоже legacy наследие древнющего до-ООП состояния фреймворка) и забыл про эту проблему. Даже не знаю, исправили в Хроме проблему или оставили, у меня и так работает :)

Почти аналогично (но даже разозлиться не успел, т.к. недолго) плясал с отсутствием вывода поля ALT в теге IMG в Хроме при отключенной графике. В итоге просто добавил небольшой JS-довесок, который в отсутствии графики меняет IMG на соответствующий текст.

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

Я не спрашиваю как можно. Я спрашиваю - как бывает :)

Это прямой намёк на то, как оно бывает :)

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

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

Я пожалуй тебе напомню, что слово «ненависть» первым употребил тут именно ты.

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

Браузеры и их умные авторы, которые всегда лучше знают, что ненужно пользователю. Да, та ещё песенка (^ ^)'

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

Ты лучше объясни, что такого полезного делает вой хелпер, что его удобнее использовать чем просто написать форму в html?

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

legacy наследие древнющего до-ООП состояния фреймворка

Сдается мне что ООП во все поля это не менее плохо чем полностью процедурное решение. Так что ты не спеши ломать свое до-ООП наследие, а то можешь пожалеть.

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

Нет, не переключаются быстро. Переключение идет чаще со сменой поколения пользователей и разработчиков. Так что вполне себе инертны и вообще лохи.

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

В итоге просто добавил небольшой JS-довесок, который в отсутствии графики меняет IMG на соответствующий текст.

И продолжаешь считать что в вэбе все ровно и гладко...

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

Браузеры и их умные авторы, которые всегда лучше знают, что ненужно пользователю. Да, та ещё песенка (^ ^)'

Про это я тоже говорил, по этому я сторонник мнения, что логику нужно максимально переносить на сервер.

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

Сдается мне что ООП во все поля это не менее плохо чем полностью процедурное решение.

Чем тебе ооп не угодило?

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

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

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

Интересно, как ты перенесёшь проверку непрогруженной картинки на сервер? (O.o)

Максимально это не значит вообще всю. Кстати проверку состояния прогруженности картинки всетаки можно перенести на сервер но не стоит.)

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

Но в принципе же можно реализовать? А там где тебе не хватит switch сделай вложенные if

Если, как в твоём примере, выбор идёт по фиксированному типу — это, конечно, нужен switch. Но вот первый же попавшийся пример из моего кода:

    if(file_exists($file = BORS_HOST.'/vhosts/'.$host.'/handlers/bors_map.php'))
        require_once($file);
    elseif(file_exists($file = BORS_LOCAL.'/vhosts/'.$host.'/handlers/bors_map.php'))
        require_once($file);
    elseif(file_exists($file = BORS_CORE.'/vhosts/'.$host.'/handlers/bors_map.php'))
        require_once($file);

Как его сделать на switch? :) Тут же логика совсем другая.

Или:

            if(preg_match('/^(\w+)\(\)$/', $key, $m)) // function(): ...
                $key = $m[1];
            elseif(preg_match('/^(\w+)&parent\(\)$/', $key, $m)) // function&parent(): ... { ... return parent::function() }
            {
                $function = $m[1];
                $class .= "\n\tfunction $function() { $value; return parent::$function(); }\n";
                continue;
            }
            elseif(preg_match('/^(\w+) \( ([^\)]+) \)$/x', $key, $m)) // function($arg): ...
            {
                $key = $m[1];
                $args = $m[2];
            }
            elseif(preg_match('/^\w+$/', $value))
                $value = "'".addslashes($value)."'";
            else
                $value = "ec('".addslashes($value)."')";

96 esleif подряд вида elseif ($_SERVER['REQUEST_URI'] == '/catalog/xxx/yyyyyy') хочется кого-нибудь убить

Правильно. Только тут убивать надо не за elseif. Если поменять на switch, то, скорее всего, получится всё равно код, требующий такого же воздействия на программиста :D

Кстати, использование суперглобальных переменных в PHP за пределами обёрток — это весьма порицаемый стиль. Я лет 13 назад такое использовал, потом, лет 10 назад чистил, когда они в $_SERVER переехали, и почти сразу пришлось чистить, как только отошёл от прямой генерации страничек. Достаточно тебе начать генерировать нужную страницу скриптом, чтобы нарваться на необходимость эмуляции всего этого окружения... А для REQUEST_URI мне пришлось изобретать то, что потом встретил под названием роутинга :)

Кстати, беда моего фреймворка — очень многие механизмы разрабатывались до того, как они стали мейнстримом и потому носят свои названия. Не route, а url_map, не backend, а storage и т.п.

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

Я же написал, что «сдается мне». Это как бы намекает на то, что у меня ощущение, что прямо срочно обморочно переписывать все под ООП не нужно. Не во всех местах это окажется хорошей идеей.

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

HTML как раз с оглядкой на реальность и делали. Просто сейчас реальность другая, делать новое не захотели.

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

В IE тоже. Я ему десять раз в ajax-запросе сказал cache: false, и всё равно он мне раз за разом показывал старый кусок страницы.
Полчаса я с ним побился и прекратил - всё равно в IE проект могу запустить только я и больше никто :)

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

Кстати, использование суперглобальных переменных в PHP за пределами обёрток — это весьма порицаемый стиль.

Это не мой код как ты понимаешь - СЕОшники чудят.

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