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

    @alexalexes
    Выводить также как из любого другого источника данных.
    1. Подготовьте источник данных.
    - Разверните службу СУБД в операционной системе сервера.
    - Выберите менеджер, чем вам будет удобно просматривать объекты СУБД.
    - Установите менеджер СУБД.
    - При помощи менеджера СУБД заведите пользователя базы данных, схему базы данных, структуру таблиц и связей, вставьте необходимые данные.
    2. Изучите способы подключения к источнику данных и взаимодействия из PHP (как делать коннект к СУБД, как подготавливать запросы и параметры к ним, как фетчить результат выборки запроса).
    3. Подключитесь к базе, выполните запрос, встройте выборку результата в ваш шаблон HTML (табы).
    Ответ написан
    3 комментария
  • Как сделать проверку на значения в переменной?

    @alexalexes
    Вариант 1. Если надо проверить одно единственное булево выражение и что-то вывести, не отходя от склейки строки:
    td>".($row["ID_EMPLOYEE"] ==1 ? "первое значение" : "второе значение")." </td>

    Вариант 2. Когда у вас возможна более толстая логика вывода в каждой ветке if:
    echo 'Перед if прекращаем шлепать HTML закрывающейся кавычкой и точкой запятой';
    if(условие)
    {
      echo 'Шлепаем HTML по истине if-а';
    }
    else
    {
      echo 'Шлепаем HTML по ИНАЧЕ';
    }
    echo 'Продолжаем шлепать HTML';
    Ответ написан
    8 комментариев
  • Какой тип должна возвразать функция при скачивании файла?

    @alexalexes
    Если возвращается идентификатор файла - тип integer.
    Если возвращается полный путь к файлу или его url - тип string.
    Если возвращаются бинарные данные содержимого файла - тип string.
    Если возвращаются raw данные из буфера ob_* вместе с http заголовками и телом файла - тип string.
    Если файл открыт файловой функцией и берется ее указатель - смотрите какой тип возвращает эта функция для указателя.
    Ответ написан
    2 комментария
  • Как хранить массив внутри value каждой опции выпадающего списка selectize?

    @alexalexes
    Если переводить массив в JSON то там тоже будут кавычки и это возможно может сломать html.

    Если вы не самописной функцией создаете строку JSON, то в функции-энкодере json_encode уже есть механизмы экранирования, чтобы ваши данные не сбежали за пределы закодированного строкой значения в JSON. (речь идет пока об абстракции JSON, принятые меры экранирования для этого уровня экранирования html не касаются!)

    Каждой опции соответствует свой массив данных, которые я планирую записать в значение value в этой форме html.

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

    @alexalexes
    Понимаю, хотите изобрести свой composer.
    $func_file_full_path = ''; // полный путь к файлу модуля с функцией
      require_once ($func_file_full_path);
      $func_name = basename($func_file_full_path,  '.php');
    
      $funct_name($func_arg1, $func_arg2....); // если попытаться вызвать переменную как функцию, то интерпретатор PHP попытается обратиться к глобальной функции по имени что содержится в этой переменной в виде строки.
      
      call_user_func($funct_name, $func_arg1, $func_arg2....); // то же самое, но в более классическом виде
    Ответ написан
    3 комментария
  • Как в php заполнить автоматически массив данными?

    @alexalexes
    $out_arr = [];
    // Тут нужно указать параметры каждого N - места в шаблоне
    $i_min = 1; $i_max = 9;
    $j_min = 1; $j_max = 9;
    $k_min = 1; $k_max = 9;
    for($i=$i_min; $i <= $i_max; $i++)
    {
      for($j=$j_min; $j <= $j_max; $j++)
      {
        for($k=$k_min; $k <= $k_max; $k++)
        {
           $out_arr[] = "ваш".$i."шаблон".$j."строки".$k;
        }
      }
    }
    var_dump($out_arr);
    Ответ написан
    Комментировать
  • Как получить timestamp,обрезав пустое время?

    @alexalexes
    komino, это проблема разработчика, а не конфига драйвера СУБД, как он будет интерпретировать значение даты в конкретном запросе, если ему не подходит статичный шаблон nls_date_format. Такой шаблон не имеет в себе лексического интерпретатора, способного выполнять условные операторы.
    Решение:
    select
    -- вариант 1
    to_char(sysdate, 'DD.MM.YYYY' || decode(sysdate - trunc(sysdate), 0, '', ' HH24:MI:SS')) as your_format_date_1, 
    -- вариант 2
    case
      when sysdate - trunc(sysdate) > 0
      then to_char(sysdate, 'DD.MM.YYYY HH24:MI:SS')
      else to_char(sysdate, 'DD.MM.YYYY')
    end as your_format_date_2
    from dual;
    Ответ написан
  • Как НЕ фиксировать транзакцию после отработки php скрипта?

    @alexalexes
    $_POST['SQL'];
    Ой, вы доверяете клиенту настолько, что позволяете ему самому формировать текст запроса для бэкенда?
    У такой модели взаимодействия уровень безопасности еще ниже, чем у подготовленных запросов со строковой склейкой параметров.
    Идеология выполнения скриптов в PHP такая, чтобы выполнить все атомарные действия, зафиксировать результат (или откатиться), отдать ответ и умереть.
    Есть какие-то примеры данного "фокуса"?

    Есть. Технология называется web sockets, она представляет другую идеологию - называется длинные запросы. Когда клиент открывает соединение с сервером и ждет от сервера сообщений (или сам их отправляет в соккет), при этом скрипт сервера в бесконечном цикле опрашивает открытый соккет. Не завершая скрипт, на сервере можно либо ожидать появление сообщения в соккете, либо выполнять что-то по транзакции, если имеется принятое сообщение.
    Проблема еще в том, что PHP не сильно приспособлен для этого режима. Вам придется делать бесконечную петлю обработки в скрипте:
    while(true)
    {
      // исполняемый код для всех клиентов соккетов
    }

    И вам нужно самим делать механизм сессий, чтобы отличать одного клиента от другого, поскольку запущенный скрипт будет принимать сообщения от всех клиентов.
    Для этих целей больше годится NodeJS. Там все соккеты разбиты по обработчикам событий, можно выделить контекст одного конкретного клиента.
    Резюмируя, могу сказать.
    а) Вы пишите свой продвинутый редактор запросов (а-ля PHPMyAdmin но с поддержкой транзакций) и у вас неправильно выбран вид сервера для бэкенда (PHP вместо NodeJS). Технические требования для взаимодействия клиента и сервера не имеют подходящей реализации технологии на сервере (web sockets).
    б) Либо у вас приложение не предполагает работы, связанной с редактированием запросов пользователем. Вы просто переносите опыт разработки desktop приложений на веб разработку.
    В этом случае вы не правильно делаете то, что формируете запросы на клиенте. Толстую бизнес-логику, предполагающую взаимодействие с базой данных с фиксацией или не фиксацией транзакции нужно переносить на бэкенд, либо в хранимые процедуры и функции СУБД.
    Ответ написан
    2 комментария
  • Как правильно заменить текст в html?

    @alexalexes
    Функция ViewGifImage не нативная, а скорее всего ее реализация прописана в какой-то подключаемой библиотеке JS.
    Нужно погуглить спецификацию этой библиотеки, и посмотреть в доках, за что отвечает параметры в функции ViewGifImage.
    Если я предположу (я не знаю, что за библиотека и не видел ее документации!), что первый параметр отвечает за указатель на html узел, куда вывалить бинарный ресурс изображения, то нужно как-то обозначить теги, чтобы указатели на эти теги выцепить из DOM через JS. Например, я хочу им задать уникальные идентификаторы:
    <img id="image-1234" src="/какой-то путь/qa_2023-02-01-212831-1.gif">
    <img id="image-5678" src="/какой-то путь/qa_2023-02-01-212831-2.gif">

    Тогда из DOM я буду доставать указатели на эти элементы через функцию getElementById.
    <script type="text/javascript">
    let image_1234 = document.getElementById("image-1234"); // тут получаем ссылку на элемент с id="image-1234"
    // далее, используем ее вместо this
    ViewGifImage(image_1234, 'sitedb/log/QA/General/SfpBCTuningCheck/gfx/qa_2023-02-01-212831-1.gif','sitedb/log/QA/General/SfpBCTuningCheck/gfx/qa_2023-02-01-212831-1.pix','322','242','ReflectionResultPlot','Frequency in MHz','0','Reflection Factor |r|','0','1','xffffff x000000 x000000 xff0000 x0000ff x00df00 xff00ff xff7f00','2','158','1','Reflection 0 Degrees','158','1','Reflection 90 Degrees','','','','','','','','','');
    
    let image_5678 = document.getElementById("image-5678"); // тут получаем ссылку на элемент с id="image-5678"
    // далее, используем ее вместо this
    ViewGifImage(image_5678, 'sitedb/log/QA/General/SfpBCTuningCheck/gfx/qa_2023-02-01-212831-2.gif','sitedb/log/QA/General/SfpBCTuningCheck/gfx/qa_2023-02-01-212831-2.pix','322','242','TransmissionResultPlot','Frequency in MHz','0','Transmission |t| in db','0','1','xffffff x000000 x000000 xff0000 x0000ff x00df00 xff00ff xff7f00','2','158','1','Transmission 0 Degrees','158','1','Transmission 90 Degrees','','','','','','','','','')
    </script>
    Ответ написан
  • Как правильно хранить секунды в базе даных?

    @alexalexes
    1. Храните в БД целочисленно;
    2. Передавайте на фронт целочисленно;
    3. На фронте преобразуйте целочисленную длительность в нужный формат любым доступным способом.
    Ответ написан
    Комментировать
  • Почему при использовании substr в php, если в тексте есть символ точки, то он считает не корректно?

    @alexalexes
    "ДокРу00001.Р1"

    Вероятно, у вас эта строка не в однобайтовой кодировке (скорее всего в utf8 работаете).
    Для таких строк нужно использовать набор функций для строк в многобайтовых кодировках, в данном случае вам нужна функция mb_substr вместо substr, иначе результат работы функций для однобайтовых кодировок в строках с многобайтовыми - не предсказуем.

    PS: не забудьте включить расширение mb_string в конфиге php сервера.
    Ответ написан
  • Как узнать процент похожести текста?

    @alexalexes
    Самое простое - натравить поисковик на собственный ресурс запросом:
    "site:yousite.ru фрагмент фразы".

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

    @alexalexes Автор вопроса
    Имя файла, получаемое при работе с модулем ZipArchive, из-за бага в этом модуле требует некоторого преобразования через промежуточные однобайтовые кодировки.
    Нужно провести такую цепочку преобразований:
    UTF-8 -> encode1 -> encode2 (encode3) -> UTF-8
    В php это будет так:
    $out_str = iconv('UTF-8', $encode1.'//IGNORE', $in_str);
    $out_str = iconv($encode1, $encode2.'//IGNORE', $out_str);
    $out_str = iconv($encode3, 'UTF-8//IGNORE', $out_str);

    Но проблема в том, что для каждой конфигурации сервера эти кодировки могут отличаться.
    Чтобы их найти нужно воспользоваться методом перебора.
    Для начала найдем все кодировки, которые поддерживает функция iconv.
    Для этого в консоли сервера вызовем:
    $ iconv -l
    Из набора кодировок нужно взять только те, которые содержат наименование "CPxxx", где xxx - число.
    С помощью скрипта провести полный перебор:
    $all_encoding = []; // сюда вставляем список всех кодировок iconv
    $out_encoding = array_filter($all_encodings, function($item){return strpos(strtolower($item), 'cp') !== false;});
      foreach($out_encoding as $encode1)
      {
        foreach($out_encoding as $encode2)
        {
          foreach($out_encoding as $encode3)
          {
              $str = iconv('UTF-8', $encode1.'//IGNORE', $out);
              $str = iconv($encode1, $encode2.'//IGNORE', $str);
              $str = iconv($encode3, 'UTF-8//IGNORE', $str);
              if($str !== false && $str !== '')
                echo $encode1.'::'.$encode2.'::'.$encode3.'::'.$str.'<br>';
          }
        }
      }

    Визуально ищем тот вариант, где имя файла восстановилось.
    В моем случае это:
    UTF-8 -> cp437 -> cp437 (cp866) -> UTF-8
    В коде это выглядит так:
    $out_str = iconv('UTF8', 'CP437//IGNORE', $in_str);
    $out_str = iconv('CP437', 'CP437//IGNORE', $out_str);
    $out_str = iconv('CP866', 'UTF8//IGNORE', $out_str);
    Ответ написан
    Комментировать
  • Зачем вложенные "namespace"?

    @alexalexes
    Потому, что класс user (с достаточно неуникальным именем) может реализован еще в каком-нибудь стороннем компоненте.
    Чтобы при подключении этого компонента, вы могли использовать одноименный класс user как из своего компонента, так и из стороннего.
    Ответ написан
  • Почему не вносятся изменения в БД?

    @alexalexes
    1. Нужно использовать подготовленные запросы, а не делать по старинке через mysqli_real_escape_string.
    2. Если вы текстом написали запрос update, он еще не начнет выполнятся, где-то нужно запустить execute.
    if(isset($_POST['ref_button']) )
    {
        $send_ref = $_POST["send_ref"];    
        $stmt = msqli_prepare($con, "SELECT * FROM usertable WHERE referral= ?");
        mysqli_stmt_bind_param($stmt, 's', $send_ref);  // s - тип данных строка, i - число, если не тот тип данных - нужно исправить
        $result = mysqli_stmt_execute($stmt);
        if(mysqli_num_rows($result) > 0)
        {
            $stmt = msqli_prepare($con, "UPDATE usertable SET owner = ? WHERE email = ?");
            mysqli_stmt_bind_param($stmt, 'ss', $send_ref, $email); // s - тип данных строка, i - число, если не тот тип данных - нужно исправить
            $result = mysqli_stmt_execute($stmt);
        }
    }
    Ответ написан
    Комментировать
  • Почему sql запрос не определяет имя таблицы, если записывать имя через prepare?

    @alexalexes
    1. В качестве входных параметров никогда не использовались имена таблиц в подготовленных запросах - это попытка забивать микроскопом гвозди.
    2. Метки для входных параметров - это не тип данных, это просто название места куда будет подставлено значение этой метки по ключу из массива значений.
    Причем, именованные метки нужно связывать со значением с помощью специальной функции:
    $stmt = $db->prepare("SELECT * FROM moya_tablitsa WHERE id = :metka_parametra_identifikatora");
    $stmt->bindParam(':metka_parametra_identifikatora', 123);
    $stmt->execute();

    Но можно не использовать именованные метки (если их несколько в запросе, то нужно вставлять значения по порядку)
    $stmt = $db->prepare("SELECT * FROM moya_tablitsa WHERE id = ?");
    $stmt->execute([123]);

    Можно использовать связывающую функцию, указав порядок метки.
    $stmt = $db->prepare("SELECT * FROM moya_tablitsa WHERE id = ?");
    $stmt->bindParam(1, 123); // 1 - это номер метки, 123 - значение параметра
    $stmt->execute();
    Ответ написан
    Комментировать
  • Как правильно указать цикл для вывода только домена?

    @alexalexes
    for($i = 0; $i < count($api['answer']['result']); $i++)
      echo $api['answer']['result'][$i]['domains'][0]['fqdn'];

    По хорошему, нужно бы еще проверять есть ли массив результата по $api['answer']['result'], если массив в $api['answer']['result'][$i]['domains'].
    Ответ написан
  • Как сделать фото с камеры HTML js?

    @alexalexes
    Комментировать
  • Как пересобрать ссылку php?

    @alexalexes
    Вот способ с parse_url, вместе с вариантами обработки ошибок.
    $url_comps = parse_url($url, PHP_URL_HOST | PHP_URL_PATH);
    if(!isset($url_comps['host']) || $url_comps['host'] !== 'music.yandex.ru')
    {
      echo 'Не Яндекс.Музыка!';
       exit;
    }
    if(!isset($url_comps['path']) || strllen($url_comps['path']) == 0 || strpos($url_comps['path'], 'album') === false || strpos($url_comps['path'], 'track') === false)
    {
      echo 'Нет параметров альбома и трека!';
    }
    $url_path_params = explode('/', $url_comps['path']);
    $url_path_params_count = count($url_path_params);
    $album = null; $track = null;
    
    for($i = 0; $i < $url_path_params_count; $i += 2)
    {
      if(isset($url_path_params[$i]) && isset($url_path_params[$i + 1]) && is_numeric($url_path_params[$i + 1]))
      {
        if($url_path_params[$i] === 'album')
           $album = $url_path_params[$i + 1];
         if($url_path_params[$i] === 'track')
           $track = $url_path_params[$i + 1];
      }
    }
    if(is_null($album))
    {
      echo 'Не задан числовой параметр альбома!';
      exit;
    }
    if(is_null($track))
    {
      echo 'Не задан числовой параметр трека!';
      exit;
    }
    $output = "https://music.yandex.ru/iframe/#track/".$album."/".$track."/";
    Ответ написан
  • Как переписать код в PDO?

    @alexalexes
    Нужно заменить на PDO аналоги функций в этих строчках:
    $conn = mysqli_connect("localhost", "root", "", "db_user");
    ...
    $sql = "SELECT * FROM users WHERE email = '".$email."' AND apiKey = '".$apiKey."'"; // а тут нужно использовать подготовленный запрос для того, чтобы безопасно добавить параметры 
                    $res = mysqli_query($db, $sql); // в подготовленном запросе на этом месте у вас будет execute-метод
                    if (mysqli_num_rows($res) != 0) {
                        $row = mysqli_fetch_assoc($res);
    ...

    PS: Вероятно, у вас проблема не в PDO, а в вообще, как переписать в подготовленный запрос.
    Ответ написан