Ответы пользователя по тегу PHP
  • Каким образом можно обеспечить aCid при условии одновременного запроса нескольких пользователей?

    IvanCher
    @IvanCher
    Мысли шире
    Сделай прокладку, через которую пользователи будут стучаться.
    Т.е. примерно по такому алгоритму:
    1. Закончился раунд, все из группы А начинают стучаться в контроллер Х
    2. Контроллер Х создает блокировку для группы А и создает новый раунд только для первого достучавшегося пользователя
    3. Другие пользователи группы А получают ответ, что кто-то уже создает новый раунд
    Ответ написан
    6 комментариев
  • Где найти информацию по прикладному PHP-программированию?

    IvanCher
    @IvanCher
    Мысли шире
    Разверни демку от симфони и xdebug'ом пройдись несколько раз по пути запроса клиентского. Думаю, что сразу много интересного увидишь :) Там и события, и компиляция, и DI, и слабая связанность, и много всего другого. Самое главное, что реализовано толково, я бы даже сказал академически правильно. Ну насколько это возможно сделать на "академически странном" языке php.
    А затем попробуй на этом же фреймворке реализовать какое-нибудь простое приложение, например, которое просто принимает от клиента запросы по АПИ и что-нибудь делает простое.
    Ответ написан
    Комментировать
  • Быстрее ли несколько параллельных запросов одного последовательного?

    IvanCher
    @IvanCher
    Мысли шире
    В распараллеливании смысл, конечно, есть. Просто это должно делаться на всех уровнях. Апач не использовал уже несколько лет, поэтому тут ничего сказать не могу, но судя по описанным симптомам, затыком у тебя является БД.
    Конкретно с firebird не работал, но наверняка её можно распараллелить через репликации.
    Т.е. сейчас у тебя получается 3 php-скрипта делают запросы к бд. Бд обрабатывает запросы синхронно, поэтому никакого выйгрыша в скорости не получается. Можно либо в настройках бд поискать асинхронную обработку запросов, но врядли там такое есть, либо реплицировать бд по типу мастер-слейв и запрашивать с разных слев-серверов бд данные, тогда прирост в скорости будет.
    Ответ написан
    Комментировать
  • Правильно ли я понимаю паттерн модели из MVC?

    IvanCher
    @IvanCher
    Мысли шире
    Вы представляете себе, что Модель это что-то конкретное, но на деле это просто абстрактный слой и Вы сами решаете какие классы в него входят, а какие нет. На деле в модели содержится ВСЁ, что связано с данными и бизнес-логикой над ними. Далее идет уже реализация, которая может быть очень и очень разной. Например, есть шаблоны проектирования ORM DataMapper и ActiveRecord. Они чуть ли не противоположно разные в реализации, но они обе модели. При этом есть более низкоуровневые архитектуры, например Domain Driven Development и Data Driven Development. В обоих случаях уровень Модели может быть размазан на несколько слоёв приложения.
    Я сейчас работаю в проекте с Domain Driven и там модель размазывается просто на кучу слоёв приложения. Как она будет размазана завист от того, какие слои для своего приложения Вы сами определили изначально.
    И Ваше утверждение, что большинство фреймворщиков ничего не понимают в этом - полная глупость. Фреймворк Симфони - это просто эталон академичности проектирования в пхп. На его основе Ларавель - тоже достаточно грамотный фреймворк. Есть еще Yii, которые пошли другим путем, но тоже очень четко разделяют внутри модель MVC, хотя и дают много возможности наговнокодить и всё смешать в кучу.
    Тут скорее Вы не понимаете, что модель - это не что-то конкретное, а лишь один из 3х компонентов, из парадигмы mvc, ответственный за хранение и изменение состояния данных. Реализаций может быть столько сколько существует программистов и даже больше.
    Еще более неопределенное - это то, как взаимодействуют эти 3 компонента из MVC между собой. Они могут на основе событийной модели взаимодействовать, или явно вызывая друг друга, и еще огромным числом разных способов.
    Касательно Вашего примера, то Вы описали слой хранения данных, переходящий в модель. Моделью, в Вашем случае, является 3ий уровень - строка таблицы(ну может и таблица тоже). 1ый уровень у Вас - это уровень, который должен синхронизировать модель с хранилищем данных. Причем таких "синхронизаторов" может быть несколько и хранилища могут быть очень разными. Например ORM и ODM. Они будут проэцировать и синхронизировать модели с хранилищями данных, но по сути к моделям они не относятся, хотя если нам нужно их всё же определить только в рамках MVC, то это конечно же будет моделью. Но в mvc есть много вещей, которые не относятся ни к одному из этих 3х компонентов, а являются связующими звеньями этих компонентов, например те же ORM, ODM, валидаторы(иногда их в модель зашивают, хотя они могут использоваться и во вне), роутинг, событийные компоненты, логер и прочее-прочее.
    Ответ написан
    4 комментария
  • Плохое ли подключение в конструторе бд?

    IvanCher
    @IvanCher
    Мысли шире
    Тем плохо, что кол-во экземпляров этих классов будет равно кол-ву открытых соединений с БД. Плюсом экземпляры класса могут умереть неожиданно, а соединения будут висеть не закрытыми, что не очень хорошо.
    Нужно стремиться к тому, чтобы было минимальное кол-во соединений с бд.
    Denis Derepko дал правильное направление тебе.
    Ответ написан
    Комментировать
  • Как быстро сравнить две разные ссылки на одинаковый адрес без curl?

    IvanCher
    @IvanCher
    Мысли шире
    Можешь попробовать приводить все входящие данные url к одному виду(canonical) и хранить этот вид в базе в отдельной колонке.
    Допустим, сперва определяешь сколько уровней домена.
    ecco.ru - 2 уровня (ecco и ru),
    men.ecco.ru - 3 (men, ecco, ru),
    www.men.ecco.ru - 4 (www, men, ecco, ru)
    Сделать это можно как-то так:
    $urls = "www.ecco-shoes.ru
    www.ecco-shoes.ru
    http://ecco-shoes.ru
    https://www.ecco-shoes.ru/
    www.ecco-shoes.ru/
    ecco-shoes.ru
    www.ecco-shoes.ru/?
    www.ecco-shoes.ru/#
    www.ecco-shoes.ru/index.php";
    
    $urls = explode("\n", $urls);
    
    foreach ($urls as $url) {
    	$hostname = parse_url($url, PHP_URL_HOST);
    	$domains = explode('.', $hostname);
    	
    	echo $url."<br/>";
    	echo $hostname."<br/>";
    	
    	foreach ($domains as $domain) {
    		echo $domain."<br/>";
    	}
    	
    	echo "<br/><br/>";
    }

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

    И всё, затем проверяешь был ли уже такой урл простым запросом в бд по колонке с каноничным урлом.
    Ответ написан
    Комментировать
  • Личные сообщения структура?

    IvanCher
    @IvanCher
    Мысли шире
    Не понял зачем здесь таблица users_messages, если все связи уже есть в messages.
    Вместо неё сделайте таблицу dialogs: id | from_user_id | to_user_id | date. А таблицу messages привести к виду: id | dialog_id | user_id | text | date
    Алгоритм такой:
    1. Ю1 начинает диалог с Ю2 - добавляем запись в таблицу dialogs. В поля from_user_id и to_user_id заносим айдишники юзеров Ю1 и Ю2 соответственно.
    2. Ю1 пишет Ю2 - добавляем запись в таблицу messages. В поле user_id ставим айдишник юзера Ю1, в dialog_id ставим айдишник текущей беседы, с остальными полями думаю понятно.
    3. Ю2 отвечает Ю1 - добавляем запись в таблицу messages. В поле user_id ставим айдишник юзера Ю2, в dialog_id ставим айдишник текущей беседы.


    Собственно всё :)

    Если диалогов как таковых нет, то из алгоритма шаг 1 вычёркиваете и таблицу соответствующую удаляете.

    Выборку затем делаете что-то типа:
    /* Выбираем все сообщения в хронологическом порядке из диалога с id = :some_dialog_id */
    SELECT m.*
    FROM messages m
    INNER JOIN dialogs d ON d.id = m.dialog_id
    WHERE d.id = :some_dialog_id
    ORDER BY m.date ASC
    Ответ написан
    1 комментарий
  • Почему эти циклы разные но работают одинаково?

    IvanCher
    @IvanCher
    Мысли шире
    Может стоит всё же сперва подучить php ? Он очень легкий, за пару вечером освоите.
    Если коротко, то скажу так - php это язык программирования, который читается интерпретатором и выполняется только та часть, что находится между "<?php" и "?>".
    Если это конец файла, то закрывающего тега "?>" может не быть. Вместо "<?php" может быть написано просто "<?".
    Всё, что не в этих тегах, то не считается интерпретатором за язык программирования и выводится на экран, как есть.
    Внутри php-кода нельзя открывать еще один блок php-кода. То есть между "<?php" и "?>" мы не можем еще раз написать "<?php", будет сразу ошибка синтаксическая.
    В современных версиях php условие if записывается ввиде
    if (true) {
    // some actions
    }

    Но допустима и запись в старом виде
    if (true):
    // some actions
    endif;

    С циклом while история аналогичная.

    Не знаю зачем я пишу тут такие основы, ведь если Вы не удосужились открыть хоть что-то и прочитать про php, то вряд ли и это прочтёте, но всё же а вдруг ... :)

    Надеюсь как-то смог помочь.
    Ответ написан
    Комментировать
  • Как лучше сделать несколько языков?

    IvanCher
    @IvanCher
    Мысли шире
    Пишу самописный движок одного сайта.

    Не буду даже объяснять насколько нелепа затея.
    Просто несколько вопросов, которые Вам лучше самому себе задать и ответить:
    • С какими цмс и фреймворками Вы уже работали и насколько глубоко их знаете ?
    • С каким кол-вом проектов в целом уже сталкивались, какие сложности возникали ?
    • На какой тип проектов рассчитана Ваша cms ?
    • Какие готовые решения будете брать за основу ?

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

    Какой htaccess ? А если "сайт взлетит" и придется nginx поставить ? :) Ладно, шучу, не взлетит ни сайт, ни cms, так что за это не беспокойтесь :)

    По сути Вашего вопроса.
    У Вас должен быть слой, который отвечает за сопоставление запроса к некоторому контроллеру/действию/методу/еще чему-то. Назовем данный слой Router.
    А у Router'a может быть такая логика: если после домена идёт /(ru|en|pl), то установить в сессию или куку соответсвующее значение текущего языка.
    В коде, где выводите какой-либо текст, то оборачиваете этот текст в метод перевода. Например, пусть это будет статический метод Translator::trans($message). Внутри статического метода берёте из сессии/куки текущий язык и смотрите есть ли данное сообщение для такого языка. Ну а дальше развивайте логику, как хотите.
    Ответ написан
  • Docker как локальный web-сервер (замена Open Server, Xampp и т.д.)?

    IvanCher
    @IvanCher
    Мысли шире
    Странные конечно ответы отмечены решениями, меня это несколько удивляет.
    Немного расскажу автору вопроса про вагрант и докер, в чем разница.
    Вагрант - это лишь обертка над virtualbox для создания заранее сконфигурированной машины в виртуалбоксе. Польза от него есть, но только для разработчиков. На продакшн сервер Вы не сможете развернуть то же окружение при помощи вагранта.

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

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

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

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

    Удачи, надеюсь мой комментарий был Вам полезен.
    Ответ написан
    11 комментариев
  • PHP скрипт открывается как текст и не выполняется. В чем причина?

    IvanCher
    @IvanCher
    Мысли шире
    Вам нужно понимать, что происходит, когда запрос доходит до веб-сервера.

    Сперва веб-сервер (обычно Apache или Nginx) получают запрос и принимают решение, что делать с ним дальше. Если нет правила для такого запроса, то они просто попытаются найти файл и отдать его, как статический. В вашем случае так и происходит. Часто веб-серверу пишут правило типа "если запрос заканчивается на .php, то передай его на исполнение php (mod-php, php-fpm, php-fastcgi и т.п.), а полученный от php ответ верни клиенту (браузеру, как правило)".

    Я использую во время разработки встроенный php-веб-сервер, но не вздумайте его использовать на живом проекте. На реальном сервере с проектом лучше использовать nginx+php-fpm.
    В unix-подобных системах встроенный пхп-веб-сервер запускается очень просто:
    - Через консоль(терминал) заходите в папку с проектом и пишете "php -S localhost:8000".
    - После этого в браузере заходите на урл localhost:8000 и Ваш проект работает.
    Если Вы работаете на windows, то быстрее осваивайте линукс\mac и разрабатывайте сразу на нормальных системах. Или, как я раньше делал, на виртуалке поднимайте сервер и на нем разрабатывайте.
    Ответ написан
    5 комментариев
  • Где правильнее проверять пользовательские данные? В контроллере или модели?

    IvanCher
    @IvanCher
    Мысли шире
    За работу с данными должна отвечать модель. Именно модель должна знать какие данные допустимы, а какие нет, потому что на ней лежит функция обработки/записи этих самых данных.
    У контролера цель - обрабатывать пользовательские запросы и решать, как на них ответить.
    Иными словами, вы принимаете данные с формы контролером и говорите модели сказать валидные ли данные пришли. Модель отвечает контролеру, контролер принимает решение, как на это ответить пользователю (ошибкой, каким-то конкретным представлением и т.п.).
    UPDATE
    MVC советую всем прочесть, прежде, чем давать странные советы. Особенно внимательно прочесть "Наиболее частые ошибки", как раз говориться, что делать из контролера Толстый Тупой Уродливый Контролер - не правильно по определению шаблона. Можно спорить сколько угодно, но об этом прямо многие авторитеты. Другое мнение сформировано отсутствием глубокого понимания MVC и малым опытом на крупных проектах.
    Ответ написан
    17 комментариев
  • Какой фрэймворк выбрать Yii 2 или Symfony 2?

    IvanCher
    @IvanCher
    Мысли шире
    Симфонисты не работают с yii2 и не до конца понимают о чем пишут :)
    Я скажу так: оба фреймворка на высоте, по возможностям одинаковы, но подходы очень разные.
    Объективно скажу так: на yii2 не получится запускать отдельные модули без запуска всего приложения, тут у симфони2 огромный плюс. Так же у симфони более классные консольные команды для генерирования каркасов, мне больше нравится, чем gii(но дело вкуса). Но по факту большинство сильных сторон симфони не оправдывается в связи с высоким порогом вхождения. Найти хорошего симфони программиста намного сложнее, чем найти его на yii2. Поэтому взависимости от бюджета и масштаба проекта можете выбирать. Симфони2 - это больше уровень корпораций, yii2 более простой при практчески том же функционале.
    Если знаете симфони2, то лучше подтяните его. Yii2 изучить намного проще, намного всё прозрачнее внутри работает, там Вам хватит пару вечеров, чтобы пройтись по исходникам и всё для себя понять как изнутри как работает.
    Ответ написан
    7 комментариев
  • PHP Рекурсивный обход данных из базы?

    IvanCher
    @IvanCher
    Мысли шире
    $sourceArray = *предполагаю, что извлекли все записи из базы*;
    $newArray = [];
    foreach ($sourceArray as $el) {
        if ($el['parent_id']) {
            $newArray[$el['parent_id']]['children'] = [
                'id' => $el['id'],
                'text'=>$el['text'],
                ...
            ];
        } else {
            $newArray[$el['id']] = [
                'id' => $el['id'],
                'text'=>$el['text'],
                ...
            ];
        }
    }

    подойдет ?
    Ответ написан
  • Возможно ли сделать что то подобное?

    IvanCher
    @IvanCher
    Мысли шире
    Эти возможности появились в php 5.4. https://php.net/manual/ru/migration54.new-features.php
    Что про них читать, я даже ума не приложу. Чего тут читать ? Функция возвращает массив, значит можешь сразу обращаться к элементу этого массива по индексу.
    $user_foto = $this->getUserInfo($id)['foto'];
    $user_foto = $this->getUserInfo($id)->foto; // Если возвращается объект.

    Только проверки на существование этого делать не забывай.
    Аналогично и с созданием объекта. Не хочешь использовать промежуточную переменную, просто помести создание объекта в скобки.
    Ответ написан
    Комментировать
  • Как настроить локальный веб-сервер на OS X Yosemite?

    IvanCher
    @IvanCher
    Мысли шире
    Настройка компонентов веб-сервера, а именно - сам веб-сервер(я выбрал давно и не пожалел nginx), php-fpm, mysql - настраивается точно также, как на любом линуксе(убунта, центос и т.д.).
    Мне понравился вот этот пакетный менеджер для мака. По ссылке есть, как его установить. Дальше через него всё ставим.
    Стал писать мануал, но вот набрел на статью.
    Будут вопросы, спрашивай.
    Ответ написан
    Комментировать
  • Как разбить 2 строки на ключ и значение?

    IvanCher
    @IvanCher
    Мысли шире
    Попробуйте
    list(, $key, $value) = explode("=", $explode[0]);
    Ответ написан
  • Задача. Возможна ли подпись исходного кода файла?

    IvanCher
    @IvanCher
    Мысли шире
    Если есть доступ к исходнику, то подделать можно что угодно. Можете посмотреть в сторону обфускации, но это всё ровно не надежно будет.
    Если нужно быть уверенным, что ничего в скрипте не менялось, то я вижу только 1 вариант.
    Сам файл index.php должен просто перенаправлять запрос к Вам на скрипт по апи со всеми данными, вы обрабатываете их у себя и отвечаете скрипту index.php, index.php передает ответ от Вас пользователю.
    Простым языком файл index.php, который может любой скачать и к себе установить должен в этом случае являться просто прокси к Вашему API.
    Ответ написан
    Комментировать
  • Как указать место индексации на сервере?

    IvanCher
    @IvanCher
    Мысли шире
    Роботс закрывает от индексации. В вашем случае лучше будет использовать sitemap.
    А если по-хорошему, то весь ajax привязывайте к урлам. Идеальный вариант, который я стараюсь соблюдать последние пару лет, это когда при клике на ссылку меняется урл в браузере, но данные обновляются через ajax. Если по этой ссылке перейти, то отображается та же страница, что и подгруженная аяксом. Иными словами при клике на ссылку не должно быть разницы сработает js(ajax) или просто перейдем по ссылке.
    Ответ написан
    Комментировать
  • Почему я не могу использовать heredoc в методе?

    IvanCher
    @IvanCher
    Мысли шире
    Можете, просто уберите пробелы(табы) перед закрывающим XML;
    Закрываться он должен со слова, с которого начинался без пробелов и табов перед, то есть:
    return <<<XML
            <request>
                ...
            </request>
    XML;
    Ответ написан
    3 комментария