Задать вопрос
Ответы пользователя по тегу PHP
  • CRON Автоотправка сообщений в вк?

    @alexalexes
    Чтобы вам начать пользоваться VK API для каких-либо действий скриптом, нужно получить токен и id приложения.
    Для этого вам нужно изучить документацию разработчика https://dev.vk.com/api/getting-started разделы "Регистрация приложения" и "Авторизация пользователя" и проделать операции, которые описаны в этих разделах.

    После того, как с помощью ключа доступа вам удастся что-то отправить, то уже можете заниматься вопросом про cron.
    Ответ написан
  • Как изменить title и description на определенных страницах DLE?

    @alexalexes
    Если знаете, какая php переменная отвечает за id страницы, то перед формированием $metatags делаете переопределение всем необходимым свойствам. Статичные строки, которые будут изменяться, выносите в переменные.
    $meta_desc = 'Быстрые и качественные исследования в круглосуточном режиме работы, диагностика проводятся высококвалифицированными специалистами, профилактика здоровья';
    $meta_kw = 'sattimed.kz, диагностика, диагностический центр, МРТ, КТ, УЗИ, саттимед, рентген, радиология, магнитно-резонансная томография, рентгеновский компьютерный томограф';
    if($id == 1) // предположим, что переменная, отвечающая за id страницы - это $id, а главная страница под идентификатором 1.
    {
      $metatags['title'] = 'Главная страница'; // хотим переопределить заголовок для главной
      $meta_desc = 'Главная страница сайта'; // хотим переопределить метаописание для главной
    }
    $metatags = <<<HTML
    <meta charset="{$config['charset']}">
    <title>{$metatags['title']}</title>
    
    <meta name="description" content="{$meta_desc}">
    <meta name="keywords" content="{$meta_kw}">
    
    {$s_meta}{$robots_meta}
    
    <link rel="search" type="application/opensearchdescription+xml" href="{$PHP_SELF}?do=opensearch" title="{$config['home_title']}">
    HTML;

    Возможности DLE для этой доработки не используются, только логика php и подстановка параметров HEREDOC.
    Ответ написан
  • Как удалить строку в бд через Read Bean Php?

    @alexalexes
    Без понимания чистого SQL прослойка ORM в виде Read Bean крайне неочевидной вещью становится:
    function claim_message($msg, $msgFh, $msgTh, $uuid)
    {
      $var = R::findOne("messages", "msg_th = ? AND is_read = 0'", [$msgTh]);
      if(!is_null($var))
      {
        $delete = R::load("messages", $var->id);
        R::trash($delete);
        return $msg;
      }
      return "null; $msgTh , $msgFh";
    }

    А где тут цикл?
    Ответ написан
  • Как исправить ошибку General error: 1 near "-": syntax error in?

    @alexalexes
    Эта черточка - воспринимается как минус, поэтому имена столбцов и других объектов желательно выбирать без них, либо оборачивать в обратные кавычки, например, `article-header`.
    Ответ написан
    Комментировать
  • Как записать в одно поле 2 пути?

    @alexalexes
    Варианты решения в зависимости от задачи:
    1) Брать один из файлов и сохранять только его.
    2) Брать известное количество файлов и сохранять их свойства в разные поля таблицы catalog. Например, может быть не более двух файлов изображения - миниатюра и полное изображение. В таблице должны быть поле под миниатюру, поле под полное изображение.
    3) Брать все файлы, но в базе должна быть отдельная таблица для файлов изображений (например, catalog_image), запись которой хранит сведения об одном файле и ссылается внешним ключом к другой таблице - catalog, к записи предмета, к которой относится файл. Такая архитектура позволит хранить неограниченное число файлов для одной записи catalog.
    Ответ написан
    Комментировать
  • Как при добавлении новых записей в базу данных обновлить данные в PHP?

    @alexalexes
    Ваш вопрос правильнее звучит так:
    "У меня реализовано приложение чата в виде клиентской и серверной части.
    Когда один экземпляр приложения (клиентская часть) отправляет сообщение и оно фиксируется на сервере, необходимо, чтобы другой экземпляр приложения (клиентская часть) получил эти сведения без дополнительных манипуляций пользователя и как можно быстрей."
    Ответ:
    Есть несколько технологий общения клиента и сервера, чтобы получать актуальные сведения с сервера:
    - Длинные опросы,
    - Частые опросы,
    - Непрерывающееся соединение (web socket).
    Ответ написан
    1 комментарий
  • Почему не работает сравнение?

    @alexalexes
    Добавьте в начале скрипта заголовки:
    header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
    header("Cache-Control: post-check=0, pre-check=0", false);
    header("Pragma: no-cache");

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

    @alexalexes
    if(isset($gorod))
    {
      $city = $gorod;
    }
    else
    {
      echo 'Просто текст';
    }
    Ответ написан
    Комментировать
  • Как удалить # из url, чтобы не мешал обновлению страницы?

    @alexalexes
    Добавьте "return false" чтобы предотвратить действие по умолчанию при клике на ссылку - переход по ссылке.
    onclick="window.location.reload(); return false;"
    Ответ написан
  • Как сделать цикличный цикл php?

    @alexalexes
    Положить меню в базу данных в виде структуры:
    MENU - таблица с анонсами меню
    menu_id - код анонса меню
    public_date - дата анонса

    DISH - таблица блюд (без привязки к меню)
    dish_id - id блюда
    title - название блюда
    dish_text - текст состава

    Таблица, обеспечивающая состав меню из блюд
    MENU_CONSIST
    cons_id
    menu_id
    dish_id
    position - порядок вывода

    Имея такую структуру, можно составить запрос на вывод меню на ближайшие 30 дней:
    select *
     from menu m
      join menu_consist mc on mc.menu_id = m.menu_id
      join dish d on d.dish_id = mc.dish_id
    where m.public_date >= CURDATE()
       and m.public_date <= CURDATE() + INTERVAL 30 DAY
    Ответ написан
    Комментировать
  • Как в MODX вывести данные в зависимости от полученного значения из сниппета?

    @alexalexes
    Голый чанковый синтаксис:
    [[*alias:is=`алиас_последнего_значения_uri,_но_не_факт,_что_не_будет_пересекаться_с_одноименными`:then=`вызов_чанка_блока_или_чистый_html`]]

    С использованием сниппета If (нужно установить одноименный пакет):
    [[!If?
      &subject=`[[*alias]]`
      &operator=`==`
      &operand=`алиас_последнего_значения_uri,_но_не_факт,_что_не_будет_пересекаться_с_одноименными`
      &then=`вызов_чанка_блока_или_чистый_html`
    ]]
    Ответ написан
    Комментировать
  • Как сделать подстановку в json файл?

    @alexalexes
    Вычитать файл csv в ассоциативный массив вида:
    $city_dictionary[$en_name] = $ru_name;
    И произвести замену:
    //$data['response'][0]['cities'][0] - вы уверены, что по конечному нулевому индексу находится весь список, а не один город?
    foreach($data['response'][0]['cities'][0] as $city_key => $city)
    {
      if(array_key_exists($city, $city_dictionary))
       $data['response'][0]['cities'][0][$city_key] = $city_dictionary[$city];
    }

    После этого $data можно конвертнуть обратно в json и в нем будет заменено то, что было в словаре $city_dictionary.
    PS: Метод имеет ограничение. В текущем формате ассоциативного массива $city_dictionary нельзя разместить два равноправных варианта перевода. В случае наличия альтернативного варианта русского перевода, из csv будет извлечен в массив последний вариант.
    PS2: Ассоциативный массив словаря ограничен объемом выделенной оперативной памяти скрипта.
    Для более объемного словаря целесообразно делать выгрузку в базу данных и от туда использовать словарь, либо в memcache - архитектура технологии идеально подходит под условия вашей задачи. Но использовать и ту и другую нужно имея небольшой опыт.
    Ответ написан
  • Почему при возведении -1000 в 1/3 степень получается Nan?

    @alexalexes
    Выражение:
    $result = -1000 ** (1 / 3);
    выполняется с таким приоритетом:
    $result = -(1000 ** (1 / 3));
    Поэтому тут нет NAN.
    Ответ написан
    Комментировать
  • Как правильно вывести массив из бд и перебрать его?

    @alexalexes
    На этом фрагменте строки:
    => '{type' =>
    у вас должно закрасться подозрение, что нужно собирать вложенный объект как-то по другому, а именно:
    $taskList[] = array( // старый способ объявления массива, можно [, но не суть
    'type' => 'Feature', 
    'id' => $row->id, 
    'geometry' => // в json-е встретилась фигурная скобка (свойство-объект) - повторяю ее открытие в своей конструкции 
    [ // это хоть и объявление массива, но в определенном режиме в JSON конвертнется в объект, так как имена свойств ассоциативные
      'type' => 'Point', 
      'coordinates' =>
        [ // а тут массив останется массивом, так как о ключах ни слова (они по индексу)
        $row->coordinates,
        $row->coordinates2
        ] // конец свойства coordinates
    ] // конец свойства geometry
    
    );
    Ответ написан
    1 комментарий
  • Какая разница между генераторами и массивами?

    @alexalexes
    https://www.php.net/manual/ru/language.generators....
    foreach (xrange(1, 9, 2) as $number) {
        echo "$number ";
    }

    Если рассказать простым языком магии, то при таком вызове внутри foreach, функция xrange определяет, что ее результат не собираются записывать в отдельную переменную, а собираются перебирать по элементам.
    Поэтому, когда выполнение интерпретатора php доходит до команды as, функция xrange выполняется до первого попавшегося yield внутри этой функции и возвращает это значение. При этом, контекст функции запоминается, а также внутренний цикл:
    for ($i = $start; $i <= $limit; $i += $step) {
                yield $i;
    }

    засыпает до того момента, пока во внешнем foreach выполнение не пройдет команду as еще раз, тогда произойдет размораживание yield и извлечение следующего значения, чтобы использовать его только как один элемент $number.
    За счет того, что as меняет режим работы вызова функции xrange, получается не извлекать все подряд.
    Ответ написан
    Комментировать
  • Как сделать, чтобы неподходящие под условие не забивали лимит?

    @alexalexes
    Вариант А.
    Вы не можете гарантировать, что любой файл изображений, сведения о которых храните в базе, будет доступен физически в любой момент.
    Придется неопределенное число раз постучаться в базу и протестировать каждую запись о файле, существует ли он физически. При тесте формируем список мертвых и живых файлов. После того, как протестировали нужное кол-во живых файлов, можно делать итоговый запрос с оглядкой на список мертвых файлов.
    $need_count = 10;  // сколько требуется файлов для выборки
    $alive_count  = 0;  // сколько живых файлов
    $is_need_repeat = true; // требуется повторить попытку получить живые файлы
    $death_list = []; // сюда накапливаем список id мертвых файлов
    $alive_list = []; // сюда накапливаем список id живых файлов
    while($is_need_repeat) // Если можно делать итерационную попытку и пока не набрали нужное количество живых файлов
    {
    // Этот запрос, чтобы прощупать целостность файлов, достаточно получить только те атрибуты, которые позволяют проверить его путь и запомнить id.
    $database->setQuery("
        SELECT id
        from блаблабла
        WHERE блаблабла 
                   ".(count($depth_list) > 0 ? : ' and id not in ('.join(',',$death_list).') ' : '')." -- отсеиваем мертвые файлы из запроса, они нам не нужны
                   ".(count($alive_list) > 0 ? : ' and id not in ('.join(',',$alive_list).') ' : '')." -- отсеиваем живые файлы из запроса, мы их уже проверяли
        ORDER блаблабла
    limit 0,".($need_count - $alive_count)); // делаем лимит по оптимистичному сценарию, как будто можем получить список файлов, и все они будут живые, но только то кол-во, которое недостает
    while($row = mysql_fetch_assoc($request))
    {
      if(file_exists('/www/ПУТЬ/'.$row['id'].'_100.jpg'))
      {
        $alive_list[] = $row['id']; // файл живой, заносим его id в список
      }
      else
      {
        $death_list[] = $row['id']; // файл мертвый, заносим его id в список
      }
      $curr_alive_count = count($alive_list);
      $is_need_repeat = $curr_alive_count > 0 && $curr_alive_count > $alive_count && $curr_alive_count < $need_count; // необходимо продолжить попытки, если на текущей итерации получили хоть один живой файл, живых файлов на этой итерации оказалось больше, чем на предыдущей, и их кол-во не достаточно до необходимого
      $alive_count = $curr_alive_count; // вписываем кол-во живых файлов на текущей итерации для проверки в будущем цикле (чтобы сравнить результаты двух циклов)
    }
    }
    // теперь можно сделать нормальный запрос, исключив мертвые файлы:
    $database->setQuery("
        SELECT *
        from блаблабла
        WHERE блаблабла 
                   ".(count($depth_list) > 0 ? : ' and id not in ('.join(',',$death_list).') ' : '')." -- отсеиваем мертвые файлы из запроса
        ORDER блаблабла
    limit 0,".$need_count);

    Вариант Б.
    Вы можете гарантировать, что контролируете целостность файлов.
    Тогда в таблице изображений делаете колонку is_del. Когда удаляете файл, вы должны пометить запись о файле в базе как удаленную по этому атрибуту.
    Если вы все таки частично контролируете целостность, то в определенный период времени (например, запускать скрипт по cron раз в час, сутки) вам нужно пройтись по всему списку файлов в базе и проверить целостность каждого файла, и внести актуальную метку is_del.
    Тогда получать живые файлы будет чуть-чуть проще:
    $database->setQuery("
        SELECT *
        from блаблабла
        WHERE блаблабла 
               and is_del is null -- или нулю, в зависимости, что будет по умолчанию
        ORDER блаблабла
    limit 0,".$need_count);
    Ответ написан
    4 комментария
  • Как извлечь данные записи бд по кнопке?

    @alexalexes
    В href записываете get параметр id строки.
    <a href="?id=1">см. запись</a>
    Если текущий список php используется для вывода всего списка, то скрипт нужно модифицировать так, что принимая параметр id, он начал работать по логике вывода сведений одной строки. Нет параметра - выводим все.
    if(isset($_GET['id']))
    {
      // тут код или вызов функции для работы с одной записью
    }
    else
    {
      // тут код или вызов функции для вывода всего списка
    }

    В ветке кода, где работаем с одной записью, подставляем get параметр в запрос:
    msqli_prepare("текст запроса ... where id = ?"); // ставим в нужное место запроса параметрические метки
    msqli_bind_param("i", $_GET["id"]); // передаем параметр на место меток-вопросов, в каком порядке они идут
    msqi_execute();
    // msqli_fetch функция и форматированный вывод сведений

    PS: msqli_* примерно накидал, смотрите документацию, как их вызывать. Идея и порядок кода примерно такой будет.
    Ответ написан
  • Как быть с 4 уровневой вложенностью кавычек в HTML?

    @alexalexes
    На более вложенном уровне экранирования нужно два символа экранирования \
    Первый символ экранирует символ экранирования для следующего уровня.
    Второй символ экранирует кавычку, чтобы не включало закрытие кавычки на уровне PHP.
    $value = '<form method="post">
    <button type="submit" onclick="return confirm(\'Вы уверены, что хотите сменить статус на \\\'Доставлен\\\' ?\')">Доставить</button>
    </form>';

    Вариант 2. Чтобы забыть об экранировании на уровне PHP, можно воспользоваться синтаксисом heredoc, который позволит вставлять любое константное содержимое без явного экранирования.
    $value = <<<ANY_RANDOM_SYMBOLS_FOR_BORDER
    <form method="post">
    <button type="submit" onclick="return confirm('Вы уверены, что хотите сменить статус на \'Доставлен\' ?')">Доставить</button>
    </form>
    ANY_RANDOM_SYMBOLS_FOR_BORDER;
    Ответ написан
    1 комментарий
  • Как понять хорош ли код?

    @alexalexes
    Для анализа производительности необходимо в вашем скрипте поставить контрольные точки, в которых будут логироваться текущее действие. Так можно понять, на что обратить внимание.
    Например, можно составить такой лог:
    0 мс: начало скрипта
    12 мс: начало чтения файла
    24 мс: конец чтения файла
    30 мс: запрос единицы товара
    34 мс: обновление цены единицы товара
    35 мс: запрос единицы товара
    36 мс: обновление цены единицы товара
     ....
    12345 мс: конец скрипта.

    PS: Логировать можно не только время, но и используемую память, и другие интересуемые параметры в момент фиксации точки.
    Ответ написан
    3 комментария
  • Нужно ли проверять длину значений, приходящих от пользователя?

    @alexalexes
    Всегда полезно проверять мин. макс. параметры всех значений и кидать исключение в случае чего.
    А вообще, есть кейсы, где лучше поругаться на слишком большую длину сообщения.
    Например, когда будете сохранять это сообщение в СУБД MySQL в поле типа данных varchar(10000) с превышением длины, то СУБД в случае превышения длины строки по тихому сохранит первые 10000 символов, а переполненную часть - нет. Так что лучше проверить длину сообщения, и если она не соответствует регламентированной, то не давать зеленый свет для обработки.
    Ответ написан
    Комментировать