LINUX.ORG.RU
ФорумTalks

Открытое тестирование сайта

 


0

1

Здравствуйте, мои маленькие психологически зрелые личности!

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

Исходный код вы можете скачать по ссылке http://www.netboot.ru/latest.tar, сейчас это сугубо-черновой вариант только чтобы продемонстировать рабочий прототип, оценить качество кода и может быть внести своё предложение по развитию.

Проверить как оно работает вживую вы можете на сайте http://www.netboot.ru/blog/, где пока на время тестирования вы можете свободно добавлять и редактировать любые сообщения.

Как я писал ранее, я не осилил ООП, поэтому проект написан в олдскульном стиле (или депрекейтед, уж кому как), с использованием исключительно простых функций, но при этом без использования глобальных переменных! Я большой перфекционист и строг прежде всего к самому себе в плане качества работы и кода, поэтому старался писать правильно.

Так например, у меня заведено в правилах, что каждая, подчёркиваю, _каждая_ функция возращает false, всегда! Чтобы функция вернула нужный нам результат, мы должны сами, подчёркиваю, _сами_, через условия добывать этот результат. Только так. В противном случае всегда будет false, и функции, которые друг-друга вызывают, получают false и отвечают тоже false, и клиент получает ошибку. С этим у меня очень строго.

Но не смотря на это, функции всё ещё поделены логически на отдельные пространства имён, то есть, все функции, которые работают с базой данных, начинаются с префикса db_, все функции, которые работают с сессиями, начинаются с префикса session_ и т.д. Соответсвенно такие списки функций я выделил в отдельные файлы, которые назвал не-классами, в ./src/noclasses лежат .noclass.php файлики.

Весь, целиком и полностью весь проект написан на функциях и ничего нигде «случайно» не происходит. Так, если вызвать php-файл напрямую из браузера, то ничего не произойдёт, т.к. там просто объявляются функции!

Проект состоит из /index.php файлика, ./src/noclasses/*.noclass.php функций и ./src/contollers/*.php контроллеров.

В /index.php самой первой вызывается функция:

run($_SERVER['REQUEST_URI'], $_SERVER['REQUEST_METHOD']);

То есть, по-сути, чтобы сэмулировать какой-то запрос и получить на него ответ, вы можете дёргать эту функцию руками.

Далее в main.noclass.php эта функция обрабатывает запрос и выдаёт ответ.

function run($request_uri, $request_method) {

    $route = route($request_uri, $request_method);

    $buffer = process($route);

    $output = output($buffer);

    return false;

}

route() смотрит какой документ запросили и выдаёт контроллер, который должен обработать запрос.

process() запускает заданный контроллер на выполнение, контроллер возвращает ответ, сгенерированную страничку например.

output() просто отдаёт ответ клиенту.

Функция route() требует доработки, т.к. каждый запрашиваемый документ проверяется вручную, а нам нужно реализовать динамический роутинг, который будет по списку смотреть маршрут и выдавать контроллер. //TODO в общем.

function route($request_uri, $request_method) {

    $request_path = strtok($request_uri, '?');
    $request = explode('/', $request_path);
    $require = false;

    if (end($request) == '') {

        if ($request[1] == '') {
            $require = 'index.php';

            return $require;
        }

    }

    return false;

}

Функция process() занимается вызовом котроллера.

function process($route) {

    if ($route == false) {
        echo 'kernel panic: controller not found';
        return false;
    }

    $request = $route['request'];
    $require = $route['require'];

    ob_start();
    $exec = (@include($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'controllers' . DIRECTORY_SEPARATOR . $require));
    $ob_buffer_length = ob_get_length();
    $ob_buffer = ob_get_contents();
    ob_end_clean();

    if ($ob_buffer_length > 0) {
        echo 'kernel panic: buffer overflow outside of request() function in ' . $require;
        return false;
    }

    if ($exec == false) {
        echo 'kernel panic: failed to execute ' . $require;
        return false;
    }

    if (function_exists('request')) {
        $exec = request($request['request_uri'], $request['request_method'], $request['request']);

        if ($exec == false) {
            echo 'kernel panic: request() function returned false in ' . $require;
            return false;
        }

        return $exec;
    }
    else {
        echo 'kernel panic: request() function is not defined in ' . $require;
        return false;
    }

    return false;

}

Вы видите, что, если php-скрипт что-то выводит вне вызываемой функции, это приводит к «панике»: kernel panic: buffer overflow outside of request()

Каждый контроллер обязан содержать функцию request(), которая уже обрабатывает запрос и выдаёт ответ.

Вот пример такого контроллера, который обрабатывает GET и POST запросы и выводит ответ.

function request($request_uri, $request_method, $request) {

    if ($request_method == 'GET') {
        return get_index();
    }

    if ($request_method == 'POST') {
        return post_index();
    }

    return false;

}

function get_index() {

    return 'Hello World!';

}

function post_index() {

    return 'Hello World!';

}

Например, мы хотим отрисовать шаблон, тогда функция get_index будет выглядить так.

function get_index() {

    $var = array(
        'title' => 'Welcome!',
        'body' => 'Hello world!'
    );

    $view = view('index.view-get-request', $var);

    return $view;

}

И шаблон будет загружен из файла ./themes/localhost.localdomain/index.view-get-request.php

Как вы видите, не смотря на то, что код полностью написан на функциях, я бы сказал, что он напоминает чем-то ООП: на функциях тоже можно писать хорошо!

★★★★★

.tar

git тоже не осилил?

ox55ff ★★★★★
()

Как вы видите, не смотря на то, что код полностью написан на функциях, я бы сказал, что он напоминает чем-то ООП: на функциях тоже можно писать хорошо!

Ещё немного и ты изобретёшь GObject.

mono ★★★★★
()

прикольно стиль чем-то даже напомнил zx спектрум tr-dos... ну вот что-то вот в ту сторону
ещё классно три полоски мигают — это вообще такая мелочь, но признак мастера

Bad_ptr ★★★★★
()

Не смотрел исходники, но открывается всё просто как самолёт, мне нравится.

tiinn ★★★★★
()

шрифты крупноваты, надо поменьше

etwrq ★★★★★
()

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

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

к сожалению да.

контроллер добавления сообщения на сайт.

<?php

function request($request_uri, $request_method, $request) {

    if ($request_method == 'GET') {
        return get_index();
    }

    if ($request_method == 'POST') {
        return post_index();
    }

    return false;

}

function get_index() {

    $env = array(
        'title' => 'Add Post',
        'is_post_written' => false,
        'text_headers' => array(
            'title' => ''
        ),
        'text' => ''
    );

    $view = view('post.add-post', $env);

    return $view;

}

function post_index() {

    if (cross_site_request()) {
        return false;
    }

    if (empty($_POST['subject'])) {
        $_POST['subject'] = '';
    }

    if (empty($_POST['content'])) {
        $_POST['content'] = '';
    }

    if (empty($_POST['replyto'])) {
        $_POST['replyto'] = '';
    }

    $subject = $_POST['subject'];
    $content = $_POST['content'];
    $replyto = $_POST['replyto'] == '' ? false : $_POST['replyto'];
    // one-line-if must be rewritten?

    $is_post_written = post_write($subject, $content, $replyto);

    $env = array(
        'title' => 'Add Post',
        'is_post_written' => $is_post_written,
        'text_headers' => array(
            'title' => post_input_filtered($_POST['subject'])
        ),
        'text' => post_text_filtered($_POST['content'])
    );

    $view = view('post.add-post', $env);

    return $view;

}

function post_write($subject, $content, $replyto = false) {

    if (is_invalid_post_subject($subject)) {
        return false;
    }

    if (is_invalid_post_content($content)) {
        return false;
    }

    if ($subject == '') {
        $headers = false;
    }
    else {
        $headers = array(
            'title' => $subject
        );
    }

    return post_insert($headers, $content, $replyto);

}

function is_invalid_post_subject($text) {

    $text = utf8_decode($text);

    if (strlen($text) > 200) {
        return true;
    }

    return false;

}

function is_invalid_post_content($text) {

    $text = utf8_decode($text);

    if ($text == '') {
        return true;
    }

    if (strlen($text) > 10000) {
        return true;
    }

    return false;

}

Spoofing ★★★★★
() автор топика

Как вы видите, не смотря на то, что код полностью написан на функциях, я бы сказал, что он напоминает чем-то ООП: на функциях тоже можно писать хорошо!

Ещё немного, и Спуф откроет для себя функциональные ЯП.

theNamelessOne ★★★★★
()

о при этом без использования глобальных переменных!

заявляет Спуф, используя глобальные переменные налево и направо 😆

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

Ну, Ок, но хотелось бы сообщение об ошибкe

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

lnx4
()

Сайт упал Fatal error: Allowed memory size of 2097152 bytes exhausted (tried to allocate 32768 bytes) in /var/www/themes/localhost.localdomain/post.index.php on line 1 или Fatal error: Allowed memory size of 2097152 bytes exhausted (tried to allocate 20480 bytes) in /var/www/src/noclasses/post.noclass.php on line 330

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

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

я лимит увеличил. чуть позже прикручу защиту от cross_site_request и на флуд.

Spoofing ★★★★★
() автор топика

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

Это называется процедурный стиль, и не надо это подавать как что-то для неосиливших ООП)

goingUp ★★★★★
()

ещё обнаружилось что у меня кривая пагинация, спустя 1000 сообщений оно выводит не те сообщение. исправлю.

Spoofing ★★★★★
() автор топика

Так например, у меня заведено в правилах, что каждая, подчёркиваю, _каждая_ функция возращает false, всегда! Чтобы функция вернула нужный нам результат, мы должны сами, подчёркиваю, _сами_, через условия добывать этот результат. Только так. В противном случае всегда будет false, и функции, которые друг-друга вызывают, получают false и отвечают тоже false, и клиент получает ошибку.

Какой депрессивный код. Перекликается с взаимоотношениями с девушками? :))

YAR ★★★★★
()
Последнее исправление: YAR (всего исправлений: 1)

ещё меня теперь дудосят и сайт выдаёт 404, но это пофигу, как перестанут — сайт оживёт.

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

не, пажди, как это пофигу?! я посетитель твоего сайта и мне не пофигу!

сайт был твой пока ты его не опубликовал, а теперь это общественное достояние, чини давай.

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

У меня вообще не открывается :(

YAR ★★★★★
()

большое спасибо флудеру, у меня стоит ini_set('max_execution_time', 5);, и сейчас после окончания дудоса сайт всё ещё не открывается — скрипт завершает работу до того как выполнится, т.е. где-то в коде есть узкое место, что скрипт не может вывести большой объём данных.

сейчас я буду работать над этим.

спасибо, правда.

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

базу данных с флуд-атакой я слил себе на локалхост, на VDS базу очистил чтобы сайт ожил. буду работать.

ещё раз спасибо.

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

Там все забито странными рекомендациями. Очевидно, что на сайт пробрались злоумышленники.

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

Норм подход (:

Начинать стоит с паттернов и алгоритмов. Без этих знаний что пхп, что Бейсик - разницы не будет. И ты либо забьёшь на то что сейчас делаешь, либо перепишешь все с нуля.

Кстати, раз нашел в добавок свою ошибку в пагинации, после исправления, будь готов скоро повторно повесить сайт из-за limit offset в данной реализации.

Код подробно не смотрел, однако судя по ОП ад там ещё тот.

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

в пагинации

Второй раз вижу это слово. Вы точно не ошиблись в букве? Может другого чела позвать для правильной в(п)агинации?
P.S. К стати, у меня ЛОР перестал проматывать на последнее сообщение, это у меня одного так или у него украли код и он теперь неправильно работает?

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

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

Простой - это когда все понятно при любом масштабировании, и через scaffolding можно сгенерить практически готовую структуру за 5 минут.

lnx4
()
Последнее исправление: lnx4 (всего исправлений: 1)

У тебя вроде была уже гостевуха, это версия 2.0?

Anoxemian ★★★★★
()

Фичреквест: автоматическое разбиение на страницы по N сообщений при инвестировании списка (новое вверху).

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

Главное, чтобы самому было интересно! А по мере освоения языка и некоторые куски перепишешь, которые самому будут казаться сомнительными. Надо ж с чего-то начинать.

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

да, я вот уже переписал SQL запрос.

было

SELECT *, post.id as `index`, post.id as `slug` FROM post

-- извлекаем первую запись, берём автора
INNER JOIN post_history AS initial ON (initial.sub_post = post.id AND initial.id = (SELECT id FROM post_history WHERE sub_post = post.id ORDER BY id ASC LIMIT 1))

-- извлекаем последнюю запись, берём текст
INNER JOIN post_history AS current ON (current.sub_post = post.id AND current.id = (SELECT id FROM post_history WHERE sub_post = post.id ORDER BY id DESC LIMIT 1))

INNER JOIN post_text ON post_text.id = current.ref_text

-- берём последние дцать сообщений
ORDER BY id DESC LIMIT :limit OFFSET :offset;

стало

SELECT * FROM (
-- извлекаем последние дцать сообщений
SELECT *, post.id as `index`, post.id as `slug` FROM post ORDER BY id DESC LIMIT :limit OFFSET :offset
) AS post

-- берём первую запись, автора
INNER JOIN post_history AS initial ON (initial.sub_post = post.id AND initial.id = (SELECT id FROM post_history WHERE sub_post = post.id ORDER BY id ASC LIMIT 1))

-- берём последнюю запись, текст
INNER JOIN post_history AS current ON (current.sub_post = post.id AND current.id = (SELECT id FROM post_history WHERE sub_post = post.id ORDER BY id DESC LIMIT 1))

INNER JOIN post_text ON post_text.id = current.ref_text;

то есть местный дудосер задудосил сайт, отправив около 10000 сообщений.

первый вариант — джоинил все 10000 сообщений, из-за чего скрипт не успевал обрабатывать SQL запрос и завершался (крашился).

второй вариант теперь сперва берёт 10 сообщений на страницу, а только потом джоинит другие таблицы. благодаря чему скрипт обрабатывается за сущие копейки времени.

о как!

надо завести git.

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

Скажи, а зачем ты такой сложный путь выбрал? Зашел сейчас на ваше маргинальное сообщество отщепенцев и уловил суть. Форкнуть LOR (в N-й раз), идея была гораздо лучше, чем писать не понимая языкаи вообще программирования.

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

Возьми там Symfony, CakePHP или Laravel на худой конец. Вбиваешь в github ключ «forum» и находишь уже готовые CMS на одном из этих движков. Допиливаешь за неделю на свой вкус. Читая документацию, ты увидишь, как правильно применяются паттерны и как они реализованы в уже готовом продукте. Ну или продолжай страдать херней дальше.

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

Форкнуть LOR

Ни один форк не взлетел. Даже ни один другой сайт на его движке не взлетел.

grem ★★★★★
()

Здравствуйте, мои маленькие психологически зрелые личности!

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

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

второй вариант теперь сперва берёт 10 сообщений на страницу

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

Дам маленькую подсказку: подзапрос со сдвигом должен отдавать только ключи id.

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

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

понял, только ID выберать во вложенном SELECT, сделаю, спасибо.

Spoofing ★★★★★
() автор топика

А вот это нормально?

Warning: Trying to access array offset on value of type bool in /var/www/src/controllers/post.view-post.php on line 31

Warning: Trying to access array offset on value of type null in /var/www/src/controllers/post.view-post.php on line 31

Deprecated: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/src/noclasses/post.noclass.php on line 391

Warning: Trying to access array offset on value of type bool in /var/www/src/controllers/post.view-post.php on line 33

Warning: Trying to access array offset on value of type bool in /var/www/src/controllers/post.view-post.php on line 34

Warning: Trying to access array offset on value of type bool in /var/www/src/controllers/post.view-post.php on line 35

Warning: Trying to access array offset on value of type bool in /var/www/src/controllers/post.view-post.php on line 37

Warning: Trying to access array offset on value of type null in /var/www/src/controllers/post.view-post.php on line 37

Deprecated: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/src/noclasses/post.noclass.php on line 391

Warning: Trying to access array offset on value of type bool in /var/www/src/controllers/post.view-post.php on line 39

Deprecated: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/src/noclasses/post.noclass.php on line 374
tiinn ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.