Задать вопрос
  • Как сделать сортировку?

    @alexalexes
    Добавьте еще два параметра в ту часть запроса, которая отвечает за сортировку.
    order_column - по какой колонке сортировать, order_direct - в каком направлении.
    Пример с limit намекает, как это сделать.
    $limit = 'limit 0, 500';
    $order_column = 'added';
    $order_direct = 'desc';
    if(isset($_GET['order_col']))
    {
      if($_GET['order_col'] == 'updated')
        $order_column = 'updated'; // не вздумайте подставлять из GET название колонки, будет sql-инъекция!
    }
    if(isset($_GET['order_dir']))
    {
      if($_GET['order_dir'] == 'asc')
        $order_direct = 'asc'; // не вздумайте подставлять из GET название клаузы, будет sql-инъекция!  
    }
            if (isset($_GET['ajax2'])) $limit = 'limit '.(int)$_GET['offset'].', 30'; // тут застраховано от инъекции при помощи преобразования в int!
    
            $rows = fs::getObjects($sql, "order by c_object.".$order_column." ".$order_direct." ".$limit);
            $rowsCount = count(fs::getObjects($sql));
    
            if (isset($_GET['ajax2']) && !count($rows))
            {
              header("HTTP/1.0 404 Not Found");
              die;
            }

    ПС: Осталось вам дополнить вопрос, "а где мне найти шаблон формы с фильтром списка, чтобы прописать get-параметры order_col и order_dir".
    Ответ написан
    Комментировать
  • Можно ли сделать этот SVG адаптивным?

    @alexalexes
    Как избавиться от отступов в векторном файле изображения.
    Либо:
    1) Откройте файл svg в векторном редакторе, например, в Inkscape.
    2) Уменьшите область видимости холста до выступающих элементов изображения.
    3) Сохраните изменения и используйте новый вариант svg файла.
    Либо в существующих данных вручную подобрать "коробочку" без отступов. У меня вот такие числа получились.
    <svg ... viewBox="23 160 466 192"
    Тестировал на таком div блоке. Изменял ему width и height, чтобы увидеть границы svg.
    Адаптивность в svg в качестве фона div работает.
    <style>
        div.container
        {
          width: 120px;
          height: 50px;
          background: url(1.svg) no-repeat;
          border: 1px solid black;
        }
      </style>
      <div class="container">
      </div>
    Ответ написан
  • Как добавить/обновить данные в таблице MySQL, если в другой таблице соблюдается определенное условие?

    @alexalexes
    Обновлять строки по условию с подзапросом. Но проблема в том, что в утверждении не говорится, чем связаны table_1 и table_2.
    update  table_1 t1
    set  t1.column_1 = A
    where exists (select 1 from table_2 t2 where t2.какой-то-связный-ключ-с-t1 = t1.какой-то-связный-ключ-с-t2 and t2.column_1 = B)
    Ответ написан
    6 комментариев
  • Виснет страница при проигрывании аудио?

    @alexalexes
    Попробуйте вместо setinterval для отображения текущей позиции использовать подписку на специализированные события элемента audio, например, на timeupdate.
    PS: Ваш плеер на основе тэга audio, надеюсь?
    полоски прогресса и таймера в отдельный поток?

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

    @alexalexes
    Каждый уважающий себя разработчик должен пройти путь создания своего велосипеда - мессенджера.
    От простой почтовой модели данных, где в записи сообщений есть отправитель и получатель, до модели данных, содержащий беседки (они же чаты, они же диалоги - называйте как хотите).
    Но вопрос не в этом. Давайте попробуем что-то сделать с существующей моделью.
    Время сообщения у нас нет - не проблема. Время летит вперед, и id увеличиваются в ту же сторону - по возрастанию. Значит id достаточно, чтобы различать, какое сообщение пришло раньше, а какое позже.
    Отсутствует сущность беседки - тоже не проблема. Будем считать совокупность сообщений, где отправитель, в которых может быть как сам автор, так и собеседник, или получатель также может быть как сам автор, так и собеседник одной беседкой. Такую совокупность сообщений можно выделить условием: (m2.to_id = m.to_id and m2.from_id = m.from_id or m2.to_id = m.from_id and m2.from_id = m.to_id) - что и будет выделять сущность беседки в упрощенном виде. Для выделения всех сообщений, где участвует пользователь from_id будет выражение: :from_id in (m.from_id, m.to_id). Осталось сообразить, как составить подзапрос с count, чтобы выделить самые поздние сообщения.
    Где-то такой запрос получится:
    select * from messages m
     where  :from_id in (m.from_id, m.to_id)
        and (select count(*)
                  from messages m2
                 where  (m2.to_id = m.to_id and m2.from_id = m.from_id
                       or   m2.to_id = m.from_id and m2.from_id = m.to_id) 
                   and m2.id > m.id
    ) < 1
    order by id desc

    Если понадобится выделить сообщения одной беседки, то скорее всего будет такой запрос:
    select * from messages m
     where (m.to_id = :to_id and m.from_id = :from_id
     or        m.to_id = :from_id and m.from_id = :to_id)
    order by id asc
    Ответ написан
    Комментировать
  • Как переделать запрос для получения нужного ответа?

    @alexalexes
    Как-то, так.
    SELECT
    city.id,
    city.name,
    country.name,
    salary,
    country.is_here
    FROM city
    LEFT JOIN country ON city.cid = country.id
    union all
    SELECT
    city.id,
    city.name,
    country.name,
    salary + 2000,
    1
    FROM city
    LEFT JOIN country ON city.cid = country.id
    where (country.id is null or country.is_here = 0)
    Ответ написан
    Комментировать
  • Почему перестал работать file_get_contents?

    @alexalexes
    Попробуйте использовать более гибкие опции stream_context_create, в качестве одного из параметров функции file_get_contents. Попробуйте 'verify_peer' => false.
    $url = 'https://secure.example.com/test/1';
    $contextOptions = array(
        'ssl' => array(
            'verify_peer'   => true,
            'cafile'        => __DIR__ . '/cacert.pem',
            'verify_depth'  => 5,
            'CN_match'      => 'secure.example.com'
        )
    );
    $sslContext = stream_context_create($contextOptions);
    $result = file_get_contents($url, NULL, $sslContext);

    Источник.
    Ответ написан
  • Как получить только первые строки из групп строк отсортированной таблицы?

    @alexalexes

    model_id = '269'
    AND partner_id = '0'
    AND size <= '32'

    Ай-ай-ай. Все Id-шники строками заданы, не тот тип данных выбрали для столбцов.
    Выбрать первые записи от какой-то категории можно c помощью коррелирующего группирующего подзапроса (где count считается).
    SELECT id, size, price, date
      FROM prices p
      WHERE model_id = 269
           AND partner_id = 0
           AND date_time <= '2021-10-19' 
           AND (select count(*)
               from prices p2
              where  -- сюда нужно прописать параметры строк, по которым будет определяться окно счетчика
                         -- то есть, отсчет счетчика будет в пределах одного размера, одной и той же модели, одного и того де партнера.
                          p2.size = p.size
                   and p2.partner_id = p.partner_id
                  and  p2.model_id = p.model_id
                  -- а тут параметр, чем отличается одна строка счетчика от другой
                  and p2.date > p.date 
            ) < 1 -- сколько строк отсечь от категории (n + 1) ?
    order by p.date desc
    Ответ написан
  • Как создать паттерн для REGEXP_LIKE для двух значений?

    @alexalexes
    Если в СУБД вы видите функции для работы с регулярными выражениями, то это еще не значит, что реализована вся их мощь.
    Например, для вашего случая, чтобы реализовать AND, нужно, чтобы исполнитель регулярок мог обрабатывать ретроспективные или опережающие проверки.
    За функциями Oracle такого функционала не замечено, в силу того, что эта СУБД не для полнотекстового поиска, а инструмент для быстрой работы с хорошо структурированными данными.
    Ковыряние в фрагментах текста - не конек реляционных СУБД, таким системам индексируемые данные подавай.
    Поэтому функционал регулярных функций ограничен, реализованы чуть лучше чем like.
    Ответ написан
    Комментировать
  • Безопасно ли хранить .htaccess в корне сайта?

    @alexalexes
    Безопасно, если правильно организован режим доступа к файлам такого вида настройками ОС для пользователя файловой системы, в качестве которого выступает веб-сервер. Плюс, веб-сервер должен быть настроен так, чтобы не позволять отдавать содержимое этих файлов. Прямой доступ к содержимому файлам конфигураций, скриптам сайта должен предоставляться не средствами веб-сервера (ssh, ftp).
    Ответ написан
    Комментировать
  • Как изменить стиль у всех элементов одного класса через JS?

    @alexalexes
    Можно воздействовать на конкретный селектор в уже отрендеренных стилях CSS.
    document.styleSheets[i].rules[j].selectorText
    Но проблема в том, что нужно пробежаться по всем стилям (i - счетчик), в каждом стиле просмотреть текст у селектора (j - счетчик).
    Если такой найден, то изменить свойство.
    document.styleSheets[i].rules[j].style['имя_свойства'] = значение_свойства;

    Подробнее:
    https://www.w3.org/wiki/Dynamic_style_-_manipulati...
    Ответ написан
    Комментировать
  • Будет ли работать звуковая карта в наушниках(USB)?

    @alexalexes
    Если вы не любитель теплого лампового звука, то любая usb затычка сгодится.
    Ответ написан
    Комментировать
  • Присвоение через ссылку JS?

    @alexalexes
    У ссылки на объект можно менять только скалярные значения, избегая замены всего объекта. Тогда у data будет работать эффект ссылки на this.data.htmlBlocks[elementClass].views. Для переприсваивания объектов нужно брать сам this.data.htmlBlocks[elementClass].views.
    viewsHandler(elementClass){
        let data = this.data.htmlBlocks[elementClass].views;
        let now = new Date().getTime();
        if ( data.lastView && now - data.lastView / 1000 > 15 ) {
          data.views = views.count++; // views который справа за пределами функции?
          data.lastView = now;
          }
        } else {
          data.views = 2;
          data.lastView = 1;
          }
          
        }
      }
    Ответ написан
    1 комментарий
  • MySQL - выборка диалогов с тремя последними сообщениями?

    @alexalexes
    Вариант для MySQL ниже 8 версии:
    select A.*
    from 
    (
    SELECT d.id AS dialog_id, 
           d.date_latest_message,
           (select max(DM.added_date)
               from dialog_messages dm3
              where dm3.dialog_id = dm.dialog_id
           ) as datetime_latest_message,
           Dm.Id as Dm_Id,
           DM.message,
           DM.added_date
      FROM dialogs d
      join dialog_messages dm on DM.dialog_id = D.dialog_id
      WHERE (select count(*)
               from dialog_messages dm2
              where dm2.dialog_id = dm.dialog_id
              and dm2.id > dm.id -- по идент. будет эффективнее работать, чем по дате-время, к тому же первичный ключ, как правило, проиндексирован, не требуется доп. индексов
            ) < 3 -- берем только те сообщения, которые позднее опубликованы чем текущее (3 вышестоящих)
        and DATE(d.date_latest_message BETWEEN) '2020-10-01' AND '2021-10-08'
    ) A
    order by A.datetime_latest_message desc, A.Dm_Id desc

    Если MySQL версии 8 и выше, как вариант, можно взять оконную функцию row_number.
    select A.*
    from
    (
      SELECT 
             d.id AS dialog_id, 
             d.date_latest_message,
             (select max(DM.added_date)
               from dialog_messages dm3
              where dm3.dialog_id = dm.dialog_id
             ) as datetime_latest_message,
             Dm.Id as Dm_Id,
             DM.message,
             DM.added_date AS message_added_date,
             row_number() over (partition by d.id              -- окно счетчика в пределах идент. диалога
                                order by DM.Id desc    -- направление сортировки счетчика
                               ) dm_rownum -- счетчик для отсечения порций
      FROM dialogs d
      join dialog_messages dm on DM.dialog_id = D.dialog_id
      WHERE DATE(d.date_latest_message) BETWEEN '2020-10-01' AND '2021-10-08'
    ) A
    where A.dm_rownum <= 3 -- отсекаем нужное число "локальных" отсчетов
    ORDER BY A.datetime_latest_message DESC, A.Dm_Id DESC
    Ответ написан
  • Можно ли для придания интерактивности на вэб-страницах в место javascripta использовать java?

    @alexalexes
    Стандарт html верстки не запрещает использования какого-то другого языка программирования, кроме js.
    <script type="text/ваш-язык-программирования"></script>

    Только вот незадача, кроме браузера, такое решение требует установки в ОС модуля среды выполнения - будь это java или silverlight, или что-то еще.
    Как правило, типичный пользователь не обладает таким роялем в кустах, у него есть только браузер и ему наплевать, есть ли в ОС какие-то специфичные модули, он хочет видеть ваш сайт исключительно с помощью браузера.
    Так что, только javascript.
    Ответ написан
    Комментировать
  • Нужно ли фильтровать глобальные переменные в PHP?

    @alexalexes
    Можно ограничится проверками только тех данных, которые приняты от клиентской части системы и могут быть заведомо изменены пользователем так, чтобы вызвать неожиданное поведение в серверной части.
    Если один метод генерирует данные для другого метода на стороне сервера, и они без проверок не выходят транзитом через клиентскую часть приложения или через другую часть приложения, где есть канал связи (точка отказа), то можно не делать проверки в каждом методе. Важно соблюдать условие, что если какой-то элемент данных пришел от пользователя и на входе в серверной части его проверили один раз (может быть даже заэкранировали), то внутри системы этим элементом данных уже можно спокойно пользоваться.
    Нужно ли фильтровать данные из _COOKIE, _HEADER, _SERVER,
    к примеру
    ?query=
    выдает модальное окошко если запустить $_SERVER['[REQUEST_URI']

    Вы ничего не запускаете, вы просто отдаете ответ браузеру (делаете эхо) от того, что пришло в части строки адреса, где содержатся get-параметры.
    Браузер, не получив внятного описания, что ему ответили html содержимым, пытается обернуть ответ в нечто валидное по html нотации:
    <html>
    <body>
    ?query=<script>alert('о, привет!'); </script>
    </body>
    </html>

    Далее, браузер пытается воспроизвести это. Строит DOM-дерево, находит тег script, пытается выполнить у себя JS-код. На этом можно обжечься когда выводите сведения в textarea.
    $unsafe_string_for_html = "<script>alert('о, привет!'); </script>";
    echo '<textarea>'.$unsafe_string_for_html.'</textarea>';

    Чтобы такое не происходило, перед выводом небезопасных для html разметки элемента данных, нужно над ним провести экранирование.
    $unsafe_string_for_html = "<script>alert('о, привет!'); </script>";
    $safe_string_for_html = htmlspecialchars($unsafe_string_for_html);
    echo '<textarea>'.$safe_string_for_html.'</textarea>';

    Можно провести экранирование и в момент получения данных, тогда при отдаче браузеру можно будет быть уверенным, что это не выполняемые инструкции, а текстовые данные с точки зрения html. Однако, когда сохраняете в базу эти данные или делаете их обработку, нужно иметь ввиду что они прошли экранирование по html и содержание некоторых символов будет немного другое чем это проецируется в браузере.
    Ответ написан
    1 комментарий
  • Как массово изменить расширение изображений на свой фомат в MYSQL базе?

    @alexalexes
    Этим запросом крайне внимательно изучаете - удовлетворяет ли вас результат преобразования строк в result_mod_f1 из mod_f1, и result_mod_f2 из mod_f2.
    select mod_f1,  replace(mod_f1, '.png', '.webp') as result_mod_f1,
              mod_f2,  replace(mod_f2, '.png', '.webp') as result_mod_f2
    from table

    Если что-то не устраивает, переписываете replace-ы.
    Если что-то переписали, то заменяете выражения в правых частях после знака =, чтобы преобразование mod_f1 соответствовало mod_f1, а преобразование mod_f2 для mod_f2.
    /*update table
    set mod_f1 = replace(mod_f1, '.png', '.webp'),
          mod_f2 = replace(mod_f2, '.png', '.webp')*/

    Снимаете комментарий, словно собираетесь открыть защитную крышку на красной кнопке атомной бомбы и выполняете запрос.
    ПС: Желательно делать это в программном средстве, которое поддерживает режим незакрытой транзакции, чтобы можно было откатить.
    ППС: Если таблица очень большая, то лучше обновлять порциями.
    /*update table
    set mod_f1 = replace(mod_f1, '.png', '.webp'),
          mod_f2 = replace(mod_f2, '.png', '.webp')
    where mod_f1 like '%.png%'
          or mod_f2 like '%.png%'
    LIMIT 1000 */
    Ответ написан
    5 комментариев
  • Как в PostgreSQL просуммировать Киловаты, группируя их по временным интервалам?

    @alexalexes
    select p.endpoint_id,
           p.mode_start as event_start,
           (p.mode_start + p.mode_duration) as event_end,
           sum(e.kwh) as sum_kwh
    from periods p
    join energy e on e.endpoint_id = p.endpoint_id -- связываем выставленный период для прибора с показаниями прибора
                 and p.mode_start <= e.event_time -- связывание начало периода с моментом замера 
                 and (p.mode_start + p.mode_duration) > e.event_time -- связывание конца периода с моментом замера
    group by p.endpoint_id, p.mode_start, (p.mode_start + p.mode_duration)
    order by p.endpoint_id, p.mode_start

    Примечание.
    1. Запрос составлен без отладки, требуется отладка.
    2. Если периоды накладываются у одного и того же прибора, то замер, в интервале где происходит накладка, попадет в сумму в обоих периодах.
    3. Если для событий не прописан период, то они не будут учитываться. Можно написать такую связку через left join так: "... energy e left join periods p on ... ", тогда сумма неучтенной энергии упадет в отдельную строку, в которой будет отсутствовать период.
    Запрос для вывода неучтенных замеров:
    select e.endpoint_id,
           p.mode_start as event_start,
           (p.mode_start + p.mode_duration) as event_end,
           sum(e.kwh) as sum_kwh
    from  energy e 
    left join periods p on e.endpoint_id = p.endpoint_id
                 and p.mode_start <= e.event_time
                 and (p.mode_start + p.mode_duration) > e.event_time
    group by e.endpoint_id, p.mode_start, (p.mode_start + p.mode_duration)
    order by e.endpoint_id,
             p.mode_start nulls first -- ставим первой строкой сумму замеров с неучтенными значениями (в пределах одного прибора)
    Ответ написан
  • Как реализовать такое на сайте?

    @alexalexes
    Самый простой концепт:
    1. При успешной авторизации создаем переменную cookie с временем жизни равным времени жизни сессии, с доступом http only, с идентификатором сессии.
    2. Если пользователь разлогинивается, то уничтожаем переменную cookie с идентификатором сессии.
    3. При генерации страницы в php, где нужно вывести статус авторизации, проверяем наличие живой куки.
    4. Если совершаем действие, требующее авторизации, дополнительно проверяем время жизни сессии в базе данных (если такой учет ведется).
    Ответ написан
  • Когда нужно писать имя таблицы в запросе?

    @alexalexes
    Всегда обзывайте каждую таблицу в запросе кратким именем, и это краткое имя используйте в именовании колонок, тогда ни при каких условиях проблем с конфликтом имен не возникнет.
    SELECT t1.ProductCode, t2.Name
    FROM table_one as t1 -- t1 - краткий псевдоним таблицы table_one в пределах select-а
    LEFT OUTER JOIN table_two as t2 -- t2 - краткий псевдоним таблицы table_two в пределах select-а
    ON  t2.id = t1.id_client;
    Ответ написан