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

    @AndryG
    Я за семь минут сформулировал три разных ответа. Это ж надо так умудриться задать вопрос, что хрен поможешь.

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

    когда подключается PHP код выходит ошибка (не находит страницу)

    Ошибки - это нормально! Нужно найти причину и устранить ее.

    Правильно заданый вопрос - 50% ответа. Тренируйтесь излагать мысли - полезно для кодинга
    Ответ написан
    Комментировать
  • Как обновить блок после удаления и добавления и получить данные для редактирования?

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

    В общем случае вам нужно вместо $('#message').html(data); проводить манипуляции с DOM на основании data. Это вам тоже описали выше. Когда возьметесь за реализацию, то заметите, что один и тот же html код вам приходится реализовывать и на стороне сервера средствами php и на стороне браузера через jQuery. Выкрутиться из этого можно разными способами:
    - дублировать логику в двух реализациях - самый плохой вариант
    - формировать html на стороне сервера, присылать его куски в бразуер аякс-ответом, а потом встраивать в DOM
    - отдавать сервером даные только в json, а html (именно с данными) строить всегда на стороне клиента
    - возвращать в аякс ответе сгенерированный javascript код, который будет проводить нужные манипуляции в DOM :)

    Я порекомендовал бы второй вариант.

    Делаете php функции, которые формируют:

    Строку с данными
    function htmlRowData($row){
    // return IDcomment
    }

    Строку с формой редактирования
    function htmlRowFormEdit($row){
    // return ФОРМА РЕДАКТИРОВАНИЯ
    }

    Рисуете себе API вашего аякса: какие вы запросы отправляете и какие данные вы получаете, формат ответа.
    Используем родной для javascript JSON.
    В ответе сервер может возвращать такие поля:

    showMessage: text // сообщение для юзера. Вывести алертом, всплывашкой (jGrowl) или еще как

    rowAction: "insert"/"replace"/"remove"

    rowHtml: html // html код Загрузка страницы.

    В контейнер формы выводим результат функции htmlForm(NULL) // вернет html пустой формы с кнопкой ДОБАВИТЬ
    Формируем таблицу, используем while($row = mysql_fetch($q){ echo htmlRowData($row);}

    Удаление записи. Ответ сервера
    "showMessage": "Запись 45 успешно удалена",
    "rowAction": "remove",
    "rowId": 45

    JS код находит Успешное добаление записи. Ответ сервера
    "showMessage": "Запись добавлена под номером 46",
    "formHtml": "<div>пустая форма с кнопкой добавить</div>"
    "rowAction": "insert",
    "rowHtml": "<tr data-id=46><td>46<td>это коммент записи 46...</tr>"

    JS код вставляет в таблицу новую строку, забивает новое содержимое в контейнер формы

    Проблема при попытке добавить новую запись. Ответ сервера
    "showMessage": "Упс, комментарий слишком короткий",
    "formHtml": "<div>форма с заполненными полями и кнопками добавить/отменить</div>"

    JS код забивает новое содержимое в контейнер формы (полезно данные обновлять, чтобы видеть, что же ты на сервер шлешь)

    Успешное сохранение измененной записи. Ответ сервера
    "showMessage": "Запись 44 изменена",
    "formHtml": "<div>пустая форма с кнопкой добавить</div>"
    "rowAction": "replace",
    "rowId": 44,
    "rowHtml": "<tr data-id=44><td>44<td>это новый коммент записи 44...</tr>"

    JS код заменяет (jQuery.replace() ) в таблицt строку, забивает новое содержимое в контейнер формы

    Дальше пишем серверную часть.
    Для отладки запросов делаете небольшую страничку и с и в него скидываете приходящие ответы в виде текста $('#debug_div').text(data). И добиваетесьот сервера корректных резуотаттов согласно апи.

    Переходим к брузерной части.
    Читаем про делегирование обработки событий в jQuery. Навешиваем на общий контейнер формы и таблицы обработчик событий всех кнопок добаления удаления, редактирования, сохранения редактирования. Реализовуем модификации DOM, ползуемся атрибутами data-id для поиска нужных мест в table
    Для кнопок можно применить такой вариант.
    Все кнопки имеют атрибут data-ctrl=ACTION, подвязываетесь на событие:

    $('body').on('click', '[data-ctrl]'m function(){
     const $t = $(this);
     const action = $t.data('ctrl');
      
     var ajaxData = {action: "Oops"}; 
      
    
     if('remove' === action){
      ajaxData.action = "remove";
      ajaxData.rowId = $t.closest('tr[data-id]').data('id'); // кнопка удаления находится в строке данных
    }
     ...
    })
     
      $.ajax({
        ...
        data: ajaxData,
        success: function(data){
        if("remove" === data.rowAction){
         ... 
      }
    }
    )


    И ещё совет: для обкатки решения упростите ваши данные до одного поля ID - меньше js кода писать и переписывать.
    Ответ написан
    1 комментарий
  • Как создать Глобальную переменную PHP?

    @AndryG
    https://www.php.net/manual/ru/intro.memcached.php
    Будет хранить в памяти даные указанное время. Все процессы, да и приложеня, смогут добраться до этих данных.
    Есть удобные методы для правильного изменения данных (чтобы лишнего не записать, нужное не затереть и т.п.)
    Ответ написан
    Комментировать
  • Как правильнее сделать такой функционал?

    @AndryG
    Основная фишка задачи в том, что вы указали даты, разбили прямую времени на диапазоны и прокомментировали лишь часть из них. А еще есть другие диапазоны. Например, между 17 часов 31 дек и 0 часов 1 янв, который в задаче не указан и если не указать на него ЗАКРЫТО, то так дойдем до диапазона по умолчанию и получим ОТКРЫТО.

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

    код
    <?php
    
    header('Content-type: text/plain');
    
    ?>31 Декабря с 8:00 до 17:00
      1 Января выходной день
      Со 2 января по 8 Января 10:00 до 23:00
      9 Января с 11:00 до 23:00
    
    <?
    $dtList = [
          ['12/31', '12/31', false, [['08:00', '17:00', true]]], // открыто
          ['01/01', '01/02', false, []], // закрыто (пустой диапазон времени)
          ['01/02', '01/08', false, [['10:00', '23:00', true]]],
          ['01/09', '01/09', false, [['11:00', '23:00', true]]],
          ['01/01', '12/31', true, [['06:00', '08:00', false]]],
    ];
    
    $dt = new dt('2020-12-28');
    $finish = (new dt('2021-01-14'))->getTimestamp();
    
    do {
        $res = false;
        foreach ($dtList as [$a1, $b1, $def, $subList]) {
            $a1 = $dt->_clone($a1);
            $b1 = $dt->_clone($b1);
            if (h::testTimeRange($dt, $a1, $b1)) {
                foreach($subList as [$a2, $b2, $c2]){
                    $a2 = $dt->_clone($a2);
                    $b2 = $dt->_clone($b2);
                    if (h::testTimeRange($dt, $a2, $b2)) {
                      $res = $c2;
                      break 2; // выход с обоих циклов
                    }
                }
                $res = $def; // первый уровень сработал, а второй не имеет подх. диапазона, значит значение по умолчанию для перв. уровня
                break;
            }
        }
        echo "\n ", $dt->format(), $res ? ' open' : ' close';
        $dt->modify('+'.rand(1, 1).' hour');
    } while ($dt->getTimestamp() < $finish);


    результат
    31 Декабря с 8:00 до 17:00
    1 Января выходной день
    Со 2 января по 8 Января 10:00 до 23:00
    9 Января с 11:00 до 23:00

    28.12.2020 00:00 open
    28.12.2020 03:00 open
    28.12.2020 05:00 open
    28.12.2020 08:00 open
    28.12.2020 09:00 open
    28.12.2020 11:00 open
    28.12.2020 12:00 open
    28.12.2020 13:00 open
    28.12.2020 15:00 open
    28.12.2020 16:00 open
    28.12.2020 18:00 open
    28.12.2020 19:00 open
    28.12.2020 20:00 open
    28.12.2020 23:00 open
    29.12.2020 02:00 open
    29.12.2020 05:00 open
    29.12.2020 06:00 close
    29.12.2020 09:00 open
    29.12.2020 12:00 open
    29.12.2020 15:00 open
    29.12.2020 17:00 open
    29.12.2020 20:00 open
    29.12.2020 22:00 open
    29.12.2020 23:00 open
    30.12.2020 02:00 open
    30.12.2020 03:00 open
    30.12.2020 06:00 close
    30.12.2020 07:00 close
    30.12.2020 10:00 open
    30.12.2020 12:00 open
    30.12.2020 15:00 open
    30.12.2020 17:00 open
    30.12.2020 19:00 open
    30.12.2020 20:00 open
    30.12.2020 23:00 open
    31.12.2020 02:00 close
    31.12.2020 05:00 close
    31.12.2020 07:00 close
    31.12.2020 09:00 close
    31.12.2020 10:00 close
    31.12.2020 13:00 close
    31.12.2020 16:00 close
    31.12.2020 19:00 close
    31.12.2020 20:00 close
    31.12.2020 23:00 close
    01.01.2021 01:00 close
    01.01.2021 02:00 close
    01.01.2021 03:00 close
    01.01.2021 04:00 close
    01.01.2021 06:00 close
    01.01.2021 09:00 close
    01.01.2021 10:00 close
    01.01.2021 11:00 close
    01.01.2021 12:00 close
    01.01.2021 13:00 close
    01.01.2021 15:00 close
    01.01.2021 16:00 close
    01.01.2021 18:00 close
    01.01.2021 20:00 close
    01.01.2021 23:00 close
    02.01.2021 00:00 close
    02.01.2021 03:00 close
    02.01.2021 06:00 close
    02.01.2021 07:00 close
    02.01.2021 10:00 open
    02.01.2021 11:00 open
    02.01.2021 12:00 open
    02.01.2021 13:00 open
    02.01.2021 14:00 open
    02.01.2021 15:00 open
    02.01.2021 16:00 open
    02.01.2021 17:00 open
    02.01.2021 18:00 open
    02.01.2021 20:00 open
    02.01.2021 23:00 close
    03.01.2021 02:00 close
    03.01.2021 04:00 close
    03.01.2021 07:00 close
    03.01.2021 10:00 open
    03.01.2021 12:00 open
    03.01.2021 13:00 open
    03.01.2021 16:00 open
    03.01.2021 17:00 open
    03.01.2021 20:00 open
    03.01.2021 22:00 open
    03.01.2021 23:00 close
    04.01.2021 00:00 close
    04.01.2021 02:00 close
    04.01.2021 05:00 close
    04.01.2021 06:00 close
    04.01.2021 09:00 close
    04.01.2021 12:00 open
    04.01.2021 13:00 open
    04.01.2021 14:00 open
    04.01.2021 15:00 open
    04.01.2021 17:00 open
    04.01.2021 19:00 open
    04.01.2021 22:00 open
    04.01.2021 23:00 close
    05.01.2021 01:00 close
    05.01.2021 02:00 close
    05.01.2021 05:00 close
    05.01.2021 06:00 close
    05.01.2021 08:00 close
    05.01.2021 10:00 open
    05.01.2021 11:00 open
    05.01.2021 14:00 open
    05.01.2021 16:00 open
    05.01.2021 17:00 open
    05.01.2021 20:00 open
    05.01.2021 23:00 close
    06.01.2021 01:00 close
    06.01.2021 03:00 close
    06.01.2021 04:00 close
    06.01.2021 05:00 close
    06.01.2021 08:00 close
    06.01.2021 09:00 close
    06.01.2021 11:00 open
    06.01.2021 13:00 open
    06.01.2021 15:00 open
    06.01.2021 18:00 open
    06.01.2021 20:00 open
    06.01.2021 22:00 open
    07.01.2021 00:00 close
    07.01.2021 01:00 close
    07.01.2021 02:00 close
    07.01.2021 03:00 close
    07.01.2021 06:00 close
    07.01.2021 07:00 close
    07.01.2021 09:00 close
    07.01.2021 10:00 open
    07.01.2021 13:00 open
    07.01.2021 14:00 open
    07.01.2021 16:00 open
    07.01.2021 17:00 open
    07.01.2021 20:00 open
    07.01.2021 23:00 close
    08.01.2021 01:00 open
    08.01.2021 02:00 open
    08.01.2021 04:00 open
    08.01.2021 05:00 open
    08.01.2021 07:00 close
    08.01.2021 09:00 open
    08.01.2021 11:00 open
    08.01.2021 14:00 open
    08.01.2021 17:00 open
    08.01.2021 20:00 open
    08.01.2021 23:00 open
    09.01.2021 00:00 open
    09.01.2021 01:00 open
    09.01.2021 02:00 open
    09.01.2021 05:00 open
    09.01.2021 07:00 close
    09.01.2021 10:00 open
    09.01.2021 12:00 open
    09.01.2021 14:00 open
    09.01.2021 17:00 open
    09.01.2021 20:00 open
    09.01.2021 22:00 open
    09.01.2021 23:00 open
    10.01.2021 01:00 open
    10.01.2021 04:00 open
    10.01.2021 05:00 open
    10.01.2021 07:00 close
    10.01.2021 10:00 open
    10.01.2021 12:00 open
    10.01.2021 14:00 open
    10.01.2021 17:00 open
    10.01.2021 19:00 open
    10.01.2021 20:00 open
    10.01.2021 23:00 open


    класс dt
    <?php
    class dt extends DateTime{
    
      /** Формат отображения даты-времени по умолчанию в игре */
      const F_DEFAULT = 'd.m.Y H:i';
    
      /**
      * Создает
      *
      * @param mixed $time
      * @param DateTimeZone $timezone
      */
      public static function createRand($time = null, DateTimeZone $timezone = null){
        $time = preg_replace_callback('@/(\d+)-(\d+)/@', function($m){
             return (string)h::rand($m[1], $m[2]);
          }, $time);
        return new self($time, $timezone);
      }
    
      /**
      * $time допускает указание нескольких доп. параметров для modify() через разделитель |
      *
      * @param mixed $time
      * @param DateTimeZone $timezone
      * @return DateTime
      */
      public function __construct($time = null, DateTimeZone $timezone = null){
        $time = explode('|', $time);
        parent::__construct($time[0], $timezone);
        while($s = next($time)){
          $this->modify($s);
        }
      }
    
      /**
      * Вывод даты согласно формату
      *
      * @param string Мо умолчнию будет общепринятый в игре вариант F_DEFAULT
      * @return string
      */
      public function format($format = null){
        return parent::format(is_null($format) ? self::F_DEFAULT : $format);
      }
    
      /**
      * Клонирует текущий объект.
      * @return dt
      */
      public function _clone($modify = null){
        $res = clone $this;
        if(!is_null($modify)){
          $res->modify($modify);
        }
        return $res;
      }
    
      public function __toString(){
        return $this->format();
      }
    
    }
    Ответ написан
    Комментировать
  • Как вычесть значение в bd через php?

    @AndryG
    Напишите триггер post delete, где запросом изменяйте значение поля в дугой таблице. Без структуры таблиц конкретнее ответ не получить.
    Ответ написан
    Комментировать
  • Как долгий PHP скрипт отправить в фон и одновременно вернуть пользователю сообщение об ожидании его исполнения?

    @AndryG
    Я в коде для таких задач имею скриптик лет 10 назад написанный:
    public static function execAsDeamon($script,$params = null){
        $tmp = '';
        foreach((array)$params as $k=>$v){
          if(empty($k)){
            continue;
          }
          $tmp .= ' -'.$k.'='.$v;
        }
        $tmp = g::options('core.php-cli-starter', 'php').' '.$script.' '.srv::$HOST_TYPE.$tmp.' > /dev/null &';
        exec($tmp);
      }


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

    Само собой, в логике приложения есть предохранитель от многократного запуска демона.
    Ответ написан
    Комментировать
  • Как определить страну прокси, убрать Китайские прокси и полностью перезаписать файл финальным результатом?

    @AndryG
    Как сделать, чтоб он не добавлял новые результаты после старых результатов, а полностью перезаписывал файл: socks5_valid.txt новыми результатами ?


    file_put_contents ($filename, $s."\r\n", FILE_APPEND);

    Убрать параметр FILE_APPEND
    Ответ написан
    Комментировать
  • Как правильно составить запрос SQL?

    @AndryG
    SELECT * FROM `brands` WHERE `district` = :district or :district = 'Не выбрано';
    Ответ написан
    Комментировать
  • Прогресс бар php?

    @AndryG
    str_pad вам в помощь. Не запутайтесь в округлениях.

    str_pad — Дополняет строку другой строкой до заданной длины

    Попробую на пальцах:

    length = 50 штук
    val = 35 %
    первыми выводим звездочек в количестве ceil(50 * 35 / 100)
    str_pad(res, ceil(50 * 35 / 100), '*')
    А потом добавляем точками до 50
    str_pad(res, 50, '.')

    В вопросе стоило упомянуть, что вас интересует консольная версия (или text/plain)
    Ответ написан
    Комментировать
  • Вывод MYSQLI с INNER JOIN и GROUP BY + ORDER. Как?

    @AndryG
    Нужно сделать просто: взять ID из TAB1, сделать JOIN с TAB2, и вывести по порядку ID, LOCAT и DATE, но отсортировав по DATE - интересны только последние даты (свежие)


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

    Если смысл наших фраз совпадает, то поступить нужно иначе. С tab2 данные нужно выбирать по двум полям (id, max(date), а у вас ключ лишь один - id. Значит сперва нужно сформировать набор данных с ключом из двух полей (id, date), а потом приджоинить к нему саму таблицу tab1, связав их сразу по двум полям. Получается выборка в два захода.

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

    select 
      t1.id, t1.raw, t2.date, t2.locat
    from ( -- формируем промежуточный набор данных с id+date подходящих записей 
    select a2.id, max(a2.date) date
    from tab2  a2 
      join tab1 a1 on a2.id = a1.id  -- этот джоин ограничивает множество a2, чтобы не группировать лишние записи
    group by a1.id, a1.date
    ) n
    join tab1 t1 on t1.id = n.id
    join tab2 t2 on t2.id = n.id and t2.date = n.date -- теперь в джоине участвует два поля, чтобы точно указать на запись, которая нам нужна


    Можете выполнить внутренний запрос отдельно и увидеть, что он вам выберет.

    Проявите уважение к отвечающим - перечитайте свой вопрос перед публикацией, оцените "доходчивость" и полноту описания + используйте форматирование :)
    Ответ написан
  • Как сделать многоуровневый роутинг праивльно?

    @AndryG
    Откройте для себя методы HTTP (get/post/put/delete/patch) - не зря их придумывали.

    Для простоты решения возьмите форму CLASS/param/param/param

    /user/234 - страница пользователя
    /user/234 - аналогично предыдущему
    albums/user/234/ - страница альбомов пользователя 234
    albums/567 - конкретный альбом пользователя (если номер альбомов сквозные)
    albums/234/6 - если нужны два поля user-num

    А вот что делать - пусть указывает HTTP метод (get/put/delete)

    Ну, или CLASS/METHOD/param/param/param
    Ответ написан
  • Почему выводится только 2 элемента вместо 3?

    @AndryG
    Книга The old man and the sea ее написал Ernst Hemingway 1899 (ernsthy@gm.com)
    Книга La Nausée ее написал Jean Paul Sartre 1905 (jps@gm.com)
    Книга The Moonstone ее написал Wilkie Collins 1824 (wilkc@gm.com)

    А у меня три. Код просто скопипастил.
    Ответ написан
    Комментировать
  • Как получить только PHPSESSID?

    @AndryG
    $str = 'mail_info_10999781={"count":4,"lastPostId":"442384768","playerId":"1","playerName":"Система","text":"За участие в Ту..","dateAdded":1586381539,"countNew":"4"}; mail_info_4180878=[]; mail_info_2329300=[]; mail_info_10982672=[]; mail_info_10524789={"count":3,"lastPostId":"444114528","playerId":"1","playerName":"Система","text":"За участие в Ту..","dateAdded":1587504640,"countNew":"3"}; mail_info_9061283={"count":3,"lastPostId":"444114548","playerId":"1","playerName":"Система","text":"За участие в Ту..","dateAdded":1587504666,"countNew":"3"}; mail_info_4767868=[]; mail_info_2307930=[]; mail_info_3713915={"count":4,"lastPostId":"444115078","playerId":"1","playerName":"Система","text":"Вы покинули или..","dateAdded":1587505121,"countNew":"4"}; mail_info_11019215=[]; uidc=75e9f7984b904a; mail_info_7521919={"count":3,"lastPostId":"444119300","playerId":"1","playerName":"Система","text":"За участие в Ту..","dateAdded":1587509668,"countNew":"3"}; mail_info_5249555={"count":3,"lastPostId":"444119305","playerId":"1","playerName":"Система","text":"За участие в Ту..","dateAdded":1587509682,"countNew":"3"}; mail_info_9721044={"count":3,"lastPostId":"444119330","playerId":"1","playerName":"Система","text":"За участие в Ту..","dateAdded":1587509739,"countNew":"3"}; mail_info_9200661={"count":1,"lastPostId":"444119783","playerId":"10978816","playerName":"Букая","text":"Перса верните","dateAdded":1587511049,"countNew":"1"}; mail_info_3775637=[]; mail_info_10950336=[]; mail_info_2728587=[]; mail_info_10799719={"count":4,"lastPostId":"444145953","playerId":"1","playerName":"Система","text":"За участие в Ту..","dateAdded":1587543962,"countNew":"4"}; mail_info_3782473={"count":4,"lastPostId":"444146002","playerId":"1","playerName":"Система","text":"Вы покинули или..","dateAdded":1587543991,"countNew":"4"}; mail_info_8929282={"count":5,"lastPostId":"444146020","playerId":"1","playerName":"Система","text":"Вы покинули или..","dateAdded":1587544010,"countNew":"5"}; mail_info_6872423={"count":4,"lastPostId":"444146071","playerId":"1","playerName":"Система","text":"Вы покинули или..","dateAdded":1587544041,"countNew":"4"}; mail_info_10947584=[]; mail_info_5361529=[]; mail_info_11024570=[]; mail_info_10824306={"count":3,"lastPostId":"444149063","playerId":"1","playerName":"Система","text":"Вы покинули или..","dateAdded":1587546093,"countNew":"3"}; mail_info_9126714=[]; mail_info_9412550=[]; mail_info_8087106=[]; PHPSESSID=720e9a61f3ce5acf34e005ba0811a4e0.1587566959.5217338; mail_info_10209738=[]; lastSyncDate=1587568026488mrush.mobi';
    if(preg_match('/PHPSESSID=(.+?);/', $str, $matches)){
        echo $matches[1];
    }else{
        echo 'Oops';
    }
    Ответ написан
    4 комментария
  • Как сделать роутинг на чистом php, перенаправляя абсолютно все запросы в index.php?

    @AndryG
    Добавлю для потомков. Единая точка входа может быть построена на более простом модуле, 99% уже используемом, - mod_dir

    Часто желательно, чтобы один файл или ресурс обрабатывал все запросы к конкретному каталогу, кроме тех запросов, которые соответствуют существующему файлу или сценарию. Это часто называют «фронтальным контроллером».

    В более ранних версиях HTTPD, этот эффект , как правило , требуется mod_rewrite, и использование из -fи -dтестов для файлов и каталогов существования. Теперь для этого требуется только одна строка конфигурации.

    FallbackResource / index . PHP
    Существующие файлы, такие как изображения, файлы CSS и т. Д., Будут обслуживаться в обычном режиме.

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



    Пример с работающего сайта:
    ...
        <Directory "$base/$proj/www/i">
          FallbackResource disabled  - в папке картинок отключаем обработчик
          Header set Cache-Control "public, max-age=31536000"
        </Directory>
    
        <Directory "$base/$proj/www">
            Options -Indexes
            Require all granted
            DirectoryIndex disabled
            DirectorySlash Off
            FallbackResource /entry.php
        </Directory>
    </Macro>
    Ответ написан
    Комментировать
  • Как преобразовать массив строк в массив чисел?

    @AndryG
    Ответ написан
    Комментировать
  • Настроить сортировку на сайте?

    @AndryG
    В сортировке по нескольким полям важно менять не только направление сортировки, но и порядок полей. Возможно, именно с порядком полей в сортировке у вас непонятки.
    Ответ написан
    Комментировать
  • Кто как укладывает бизнес правила в БД?

    @AndryG
    У нас говорят на подобную задачку "Ты собираешься на написаном для тебя интерпретаторе написать свой интерпретатор для другого программиста?"

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

    Предлагаю вам написать пяток классов, которые с кучкой переключателей и флажков реализуют тот самый десяток скелетов бизнесправил. Просто, надежно, красиво.
    Ответ написан
    2 комментария
  • Как безопасно сохранить данные с формы визуального редактора текста?

    @AndryG
    Не надо вырезать никакие теги!
    Безопасность, как и в сексе, определяется правильным применением контрацептивов :)
    При записи в БД ваши данные перед попаданием в текст запроса должны пройти через escape-обработку mysqli_real_escape_string() php.net/manual/ru/mysqli.real-escape-string.php
    При выводе в браузер ваш текст, независимо от того, ожидаете вы в нем теги или нет, должен пройти через htmlspecialchars() php.net/manual/ru/function.htmlspecialchars.php

    Эти два простые правила позволят вам получить море наслаждений с минимальным риском.

    Маленькое дополнение. Если в редакторе используется bbCode, то подумайте над хранением обеих версий текста: оригинальный текст с редактора и скомпилированный html-код. Так вам придется выполнять дорогую операцию компиляции bbCode лишь при изменении оригинала.
    Ответ написан
    8 комментариев