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

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

★★★★★

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

Капец ты бессовестный. А я тебе вполне откровенно помочь советом хотел, не обращая внимания на ваши прошлые выходки в адрес сообщества. Ну, ок. Понятно.

Собственно, противоречивое заявление:

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

Не покинешь ЛОР никогда, хочешь сказать?

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

Сейчас запал пройдёт и он забьёт на свой движок. Если бы цель была в альтернативном лоре, то нужно было форкать lorsource, а не тратить время на разработку с нуля да ещё и на умирающем языке. Тупо время закапывает.

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

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

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

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

Ты зря это затеял. Посмотри на мой проект. Я показал всем, что я могу. Делал сборки в виртуалках на пне 4 с 3 ГБ рамы даже для MacOS ppc/x86, amd64, что китайские братья из Brothersoft давали 5 звёзд, за то что какой-то чухонец из российской глубинке собрал рабочую программу, которая запустилась и работала на их оригинальных маках.
Мне народ писал, что хотим с тобой работать, думая, что это всё делают 10 людей, а не один человек-пароход, но они всё равно считают меня инфантильным за то что хочу на девственнице жениться и с бабской психологией из-за моих разговоров про энергетику людей, что всё это работает.
Запомни, завистники будут всегда. В лицо эти крысы никогда не скажут, что они завидуют. Почитай мой тред, про автор программы под ГПЛ2 нарушает гпл2, там народ писал, что типа «он написал эти проги на С++, прочитав одну книгу А.Я. Архангельского по Delphi и Макса Шлее по программирование на С++ в Qt4? - он гонит, он тролль! типа это невозможно!». И так будет всегда. Станешь начальником в фирме - автоматически будешь жополизом, так как сам ты никогда ни на что не способен. Это людская зависть не более того.

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

хочу с радостью отрапортовать, что после многочисленных флуд-атак база данных SQLite3 ниразу не сломалась. более того, я сам на локалхосте провёл ряд тестов, когда попытался вставить 1,000,000 записей.

НИ ОДНА попытка записи не выдала ошибку и база данных успешно отработала. даже после того, как сам клиент отработал, скрипт продолжал писать всю очередь, которая ещё оставалась не записана.

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

function db_connect_retry($db_dsn, $db_username, $db_password, $db_attributes, $db_timeout = 5) {

    // make own time limit
    set_time_limit($db_timeout);

    $db = false;

    while ($db == false) {
        try {
            $db = new PDO($db_dsn, $db_username, $db_password, $db_attributes);
        }
        catch (Exception $e) {
            if (stripos($e->getMessage(), 'DATABASE IS LOCKED')) {
                usleep(50000);
                continue;
            }

            return false;
        }
    }

    return $db;

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

спасибо за замечание. я погуглил, я учусь.

финальная версия запроса выглядит так

SELECT
post.id AS `id`,
initial.date_created AS `date_created`,
current.date_created AS `date_modified`,
post_text.text_headers AS `headers`,
post_text.text AS `content`
FROM (
SELECT id 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;

сюда ещё JOIN таблицы user добавится в будущем, но пока производительность уже заметна возросла даже по сравнению с SELECT *, спасибо.

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

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

только уточнил, что если сисястая HеRка позвонит и пригласит на работу за кучу денег — я откажусь, но а если предложит мне жениться на ней, а уже потом к ней на работу, то тогда да, соглашусь.

об этом все знают на текущей работе.

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

от них никуда не уйду

Этому зарплату не поднимать.

об этом все знают на текущей работе

Что ж ты так позоришься?

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

Тоже мне проблема. Схантят вместе с начальством, делов-то.

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

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

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

всё благодаря функции db_connect_retry, которая ждёт, когда очередь освободится

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

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

ещё не определился с выбором где хранить, изначально было dirname($_SERVER['DOCUMENT_ROOT']), но для тестов специально всё выбросил в /var/www.

мне понравился один трюк, когда ты находишься в /var/www/example.com, выполняешь команду find и у тебя формируется список вида

# mkdir /var/www/example.com
# cd /var/www
# find
example.com/filename1
example.com/filename2
example.com/filename3

это удобно для копипаста и работы с файлами, что локально, что через веб-сервер.

в любом случае хотя бы index.php должен находится в www директории, а уже далее можно подсасывать сорцы из /usr/share/web например.

либо делать вида /var/www/example.com/{db,src,www}

вот просто не знаю как лучше. ну пока ничего критичного нет, всё в /var/www выбросил.

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

За SELECT * FROM в коде на проде разработчиков надо пороть розгами :)

А можно аргументы?

~/git/lorsource$ git grep -i "select \*" -- "*.java" "*.scala" | wc -l
9
Tanger ★★★★★
()
Ответ на: комментарий от Rost

legacy скорее всего. Да там половина - select * from (select a,b,c ...)

@Dimez, а за использования ORM розги полагаются? ;)

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

спасибо за замечание. я погуглил, я учусь.

А вот за это жесточайший респект.

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

А можно аргументы?

  1. Добавляешь поле в БД для новой версии, конструкция SELECT * FROM, результат которой ожидает точное количество полей, ломает всё.

  2. Добавляешь поле в БД для новой версии, деплоишь код, что-то не так, откатываешь код. С новой версией БД, при SELECT * FROM ничего не работает. А при селекте заданных полей старый код отлично работает с новой версией БД.

  3. Ну и про скорость.

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

За SELECT * FROM в коде на проде разработчиков надо пороть розгами :)

А можно узнать что не так с таким подходом? У меня в кроссворде база слов в SQLite3 бд и только такими конструкциями я и пользуюсь.

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

А при селекте заданных полей старый код отлично работает с новой версией БД.

Понял. Я недопетрил сразу. У меня только выборка нужных полей. Я сразу это продумал и «SELECT * FROM» не использовал. Чтобы базу можно было модернизировать, вводить/выводить новые/ненужные поля и код не переписывать. Это я точно помню, хоть и 9 лет прошло с последних изменений кроссворда.
[UPD]

        if (CurrentTable == "w0")
            str1 = "SELECT Number, CountLetter FROM " + CurrentTable + ";";
        else
            str1 = "SELECT Number FROM " + CurrentTable + ";";
[UPD2]
        strBook = "SELECT Music, Films, Photos, Documents, Programs FROM Additional;";
        QueryAdditional.exec(strBook);
        RecordAdditional = QueryAdditional.record();
Вот так я в библиотеке выбираю все поля дополнительной информации к книгам, хотя других полей нет, но я всё равно выбираю каждое поле отдельно. Так что я 9лет назад сразу писал продакшон-код. 😜
[UPD3]
    strBook = "SELECT NameBook, Subcategory, Category, Year, PrintingHouse FROM ListBooks;";
    QueryBook.exec(strBook);
    RecordBook = QueryBook.record();
А так я загружаю список книг. А мне говорили, что мой код плохой... :(
[UPD4]
    strBook = "SELECT Pages, Images, NumberImages FROM Table" + sNumBook + ";";
    QueryBook.exec(strBook);

    if (QueryBook.record().count() == 0)
    {
        strBook = "SELECT Pages, Images FROM Table" + sNumBook + ";";
        QueryBook.exec(strBook);
    }
А так я гружу сами книги.

P.S. Первый раз в жизне выпил банку AdrenalineRush. ППц, меня распёрло... 🤣🤣🤣

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

Добавляешь поле в БД для новой версии, деплоишь код, что-то не так, откатываешь код. С новой версией БД, при SELECT * FROM ничего не работает. А при селекте заданных полей старый код отлично работает с новой версией БД.

Потому что надо писать rollback-миграции и при откатывании кода откатывать миграции тоже.

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

Это всё работает, пока БД небольшая.

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

Все равно плохой подход. Делать так никто не запрещает, но нежелательно. К тому же, дополню Димеза, не всё есть монолит. Частая ситуация когда некоторые данные используются только отдельными сервисами. Т.е. при изменение структуры в БД, у вас, при таком подходе, придется править все части системы, а не один отдельный сервис. Поэтому, лучше делать сразу правильно.

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

Поэтому лучше делать сразу правильно.

Именно так, сначала думать, потом трясти, а не наоборот, «если вы понимаете, о чём я» (с) :)

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

Если сисястая пожарница предложит тебе на ней жениться, ты её бросишь и скажешь, что виновата она.

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

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

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

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

OK, пусть будет.

xwicked ★★☆
()

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

Не могу :(. Тестирование завершено?

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

извините. разработка идёт полным ходом, сейчас мне необходимо реализовать cross_site_request(); under_stress(); captcha(); жизненно-важные функции, без которых сайт превращается в решето.

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

Пустые строки вначале/конце класса/функции мне постоянно делают нервы. Всегда думал, что это продажн^Wклятый JetBrains ввел эту моду.

urxvt ★★★★★
()

а дома тишина, чистота, покой и умиротворение, и никто слова тебе поперёк не скажет

Женись и заведи ребенка, будь мужиком :)

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

Этот жиробас ещё комменты собирает, а вы ведетесь.

Завидуешь что он в МСК переехал, $lusername?

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

Жены не нужны, дети тем более.

А я хочу 5 жён и 16 детей. Дохтор, что со мной и есть ли лякарства?

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

Насколько я видел по коду, твой сайт и так РЕШЕТО.

Zhbert ★★★★★
()

Олдскульный стиль, классно.

GREAT-DNG ★★★★
()

Проверить как оно работает вживую вы можете на сайте http://www.netboot.ru/blog/

нет, не можем

Unable to complete secure transaction

браузер Опера (да-да, та самая)

можете на сайте http://www...

curl -I "http://www.netboot.ru/blog/"
HTTP/1.1 301 Moved Permanently
Server: nginx/1.23.0
Date: Thu, 21 Jul 2022 20:40:37 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://www.netboot.ru/blog/


гуляй, Вася

PerdunJamesBond
()

В свободное от работы время, в своё удовольствие, когда <...> я занимаюсь разработкой своего проекта, сайта

капец ты задрот! нет, ну ладно еще там "долгими зимними вечерами"(тм), но блин, мужЫк, лето на дворе! ходи гулять, купаться, пиво пить на свежем воздухе, лисапед там себе заведи, вот это все. туризмом займись - пешим, велосипедным, водяным, еще каким... просто съезди куда-нибудь на выходных, посмотри интересные места поблизости... нет, буду в компутер пялиться целыми днями!
друзей заведи, что ли. если совсем задрот - хотя бы кого-нибудь из тутошних найди, кто поблизости живет, даже если из числа таких же задротов - все ж какое-никакое живое общение, всяко лучше, чем говнокодить на похапе.
у меня вот тоже проблемы с общением с людьми, и тоже живу один, но проводить лето за компом и говнокодить желания почему-то не возникает.
я худею с местной публики, все как на подбор поехавшие)))

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

Мне кажется если ТС делает минимальную физактивность для борьбы с гиподинамией и общается целый день на работе, то этого хватает для его типа характера, вы ведь слышали про холериков меланхоликов и пр? и он имеет право провести часик другой в день занимаясь своим хобби, а не посещая сомнительные алкопати илотов, тем более вы наверное еще не представляете какое концентрированное удовольствие доставляет творение, в данном случае автоматизация перекладывания байтов, как будто ты рожаешь частичку будущего искуственного интеллекта, не просто жизнь а новый вид, пусть пока примитивный и бесплодный в плане творения себе подобных, но все же… А на свежий воздух выходить бывает опасно, про это еще Щедрин писал в сказке о премудром пескаре.

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