Ответы пользователя по тегу PHP
  • Как правильно зашифровать с помощью CryptoJS?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    Комментировать
  • Как изменить цвет графика в morris js с определенной даты?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    barColors: function (row, series, type) {
        const withAd = true; // либо в PHP добавьте этот флаг, либо тут по датам определите
        return withAd ? "green" : "blue";
    }
    Ответ написан
    Комментировать
  • Допустимо ли создавать массивы в php без части элементов?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    В php ключи массива могут быть любыми.
    Можете сразу создавать с нужными ключами
    $myArray = [
        1 => $array2
    ];
    Ответ написан
  • Как сделать кнопку генерации пароля?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    <?php
    /* Функция для генерации купона */
    function generateCoupon() {
        return (object)[
            'id' => uniqid(),
            'code' => random_int(100000, 999999)
        ];
    }
    
    /* Для примера сохранять будем в сессию, а для этого первым делом убедимся что она запущена */
    if (!session_id()) {
        session_start();
    }
    
    /* Обрабатываем отправку пользователем формы - генерируем и сохраняем купон */
    if ($_SERVER['REQUEST_METHOD'] === "POST") {
        $_SESSION['coupon'] = generateCoupon();
    
        /*
         * После успешного сохранения перенаправляем пользователя на эту же страницу
         * В данном конкретном примере у нас одна страница и без этого шага при обновлении страницы браузер предпримет попытку перепослать форму при обновлении страницы
         * В более реальном коде сохранением будет заниматься отдельный обработчик и подобный код поможет вернуть пользователя обратно на страницу с формой/данными купона
         */
        header("Location: {$_SERVER['REQUEST_URI']}"); 
        die();
    }
    
    /* Вытаскиваем сохранённый купон, если таковой имеется */
    $coupon = $_SESSION['coupon'] ?? null;
    ?>
    
    <?php if (empty($coupon)) { ?>
        <form method="POST">
            <button>Сгенерировать купон</button>
        </form>
    <?php } else { ?>
        <span>Ваш купон: "<b><?= $coupon->code ?>"</b> успешно добавлен, его ID = <?= $coupon->id ?>
    <?php } ?>
    Ответ написан
    Комментировать
  • Как поместить в массив коды символов?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    function translit($value) {
        $converter = [
            '%D0%B0' => 'a',
            '%D0%B1' => 'b',
            '%D0%B2' => 'v',
            '%D0%B3' => 'g',
            '%D0%B4' => 'd',
            '%D0%B5' => 'e',
            '%D1%91' => 'e',
            '%D0%B6' => 'zh',
            '%D0%B7' => 'z',
            '%D0%B8' => 'i',
            '%D0%B9' => 'y',
            '%D0%BA' => 'k',
            '%D0%BB' => 'l',
            '%D0%BC' => 'm',
            '%D0%BD' => 'n',
            '%D0%BE' => 'o',
            '%D0%BF' => 'p',
            '%D1%80' => 'r',
            '%D1%81' => 's',
            '%D1%82' => 't',
            '%D1%83' => 'u',
            '%D1%84' => 'f',
            '%D1%85' => 'h',
            '%D1%86' => 'c',
            '%D1%87' => 'ch',
            '%D1%88' => 'sh',
            '%D1%89' => 'sch',
            '%D1%8C' => '',
            '%D1%8B' => 'y',
            '%D1%8A' => '',
            '%D1%8D' => 'e',
            '%D1%8E' => 'yu',
            '%D1%8F' => 'ya',
        ];
        
        $decodedKeys = array_map(function($encodedKey) { 
            return urldecode($encodedKey);
        }, array_keys($converter));
        $converter = array_combine($decodedKeys, array_values($converter));
        
        return strtr($value, $converter);
    }
    Ответ написан
    1 комментарий
  • Возможно вывести содержимое шорткода без wordpress?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    Нужно реализовать аналоги функций add_shortcode и do_shortode, соответственно.
    Вот документация, в ней описано и как они работают и исходный код можно посмотреть:
    https://developer.wordpress.org/reference/function...
    https://developer.wordpress.org/reference/function...
    Ответ написан
    1 комментарий
  • Как в цикле foreach удалить массив из многомерного массива по ключу?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    Если есть вероятность, что ключа stocks не будет на месте, то не забудьте добавить соответствующую проверку.
    Аналогично с type

    foreach ($items as $itemIndex=>$item) {
        foreach($item['stocks'] as $stockIndex=>$stock) {
            if ($stock['type'] === "fbo") {
                unset($items[$itemIndex]['stocks'][$stockIndex]);
                $items[$itemIndex]['stocks'] = array_values($items[$itemIndex]['stocks']);
            }
        }
    }
    Ответ написан
    3 комментария
  • Как найти два слова в диапазоне нескольких символов между ними?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    Код предполагает, что в каждой строке искомое слово может встречать не более одного раза.
    То есть, в строке типа "word.........17199,word" пара найдена не будет.

    function findPair(string $text, array $words, int $range=5) {
        $rows = explode(PHP_EOL, $text);
        $numberLength = 5;
        $pair = null;
        $isNumberFound = false;
        
        foreach ($words as $word) {
            foreach ($rows as $row) {
                $wordPos = strpos($row, $word);
                $isWordInRow = $wordPos !== false;
                
                if (!$isWordInRow) {
                    continue;
                }
                
                
                
                /* Going backwards first */
                $backwardSearchStart = $wordPos-1;
                $backwardSearchEnd = $backwardSearchStart - $range;
                
                for ($symbolPos=$backwardSearchStart; $symbolPos>$backwardSearchEnd; $symbolPos--) {
                    // Stop backward search if we are in the very beginning of the row
                    if ($symbolPos <= 0) {
                        break;
                    }
    
                    $symbol = substr($row, $symbolPos, 1);
                    
                    if (is_numeric($symbol)) {
                        $lastNumberPos = $symbolPos - $numberLength;
                        $digits = [];
                        
                        for ($digitPos=$symbolPos; $digitPos>$lastNumberPos; $digitPos--) {
                            $digit = substr($row, $digitPos, 1);
                            
                            if (is_numeric($digit)) {
                                $digits[] = $digit;
                            } else {
                                break;
                            }
                        }
                        
                        $isNumberFound = count($digits) === $numberLength;
                        
                        if ($isNumberFound) {
                            $number = implode(array_reverse($digits));
                            $pair = [$word, $number];
                            break;
                        }
                    }
                }
                
                if ($isNumberFound) {
                    return $pair;
                }
                
                
                
                /* Forward search */
                $forwardSearchStart = $wordPos+1+strlen($word);
                $forwardSearchEnd = $forwardSearchStart + $range;
                
                for ($symbolPos=$forwardSearchStart; $symbolPos<$forwardSearchEnd; $symbolPos++) {
                    $symbol = substr($row, $symbolPos, 1);
                    
                    if (is_numeric($symbol)) {
                        $lastNumberPos = $symbolPos + $numberLength;
                        $digits = [];
                        
                        for ($digitPos=$symbolPos; $digitPos<$lastNumberPos; $digitPos++) {
                            $digit = substr($row, $digitPos, 1);
                            
                            if (is_numeric($digit)) {
                                $digits[] = $digit;
                            } else {
                                break;
                            }
                        }
                        
                        $isNumberFound = count($digits) === $numberLength;
                        
                        if ($isNumberFound) {
                            $number = implode($digits);
                            $pair = [$word, $number];
                            break;
                        }
                    }
                }
                
                if ($isNumberFound) {
                    return $pair;
                }
            }
        }
        
        return $pair;
    }
    
    $words = ["apple", "word", "new"];
    $text = <<<TEXT
    what, 10924
    59012, test
    VT 92918
    word, 18913
    site 85719
    12345 Wisconsin
    TEXT;
    
    
    $pair = findPair($text, $words);
    /* Result: 
    array(2) {
      [0]=>
      string(4) "word"
      [1]=>
      string(5) "18913"
    }
    */
    Ответ написан
    Комментировать
  • Как безопасно разрешить отправлять ссылки в базу и выводить их в дальнейшем?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    Более или менее надёжен HTML Purifier в этом вопросе (htmlpurifier.org)
    Ответ написан
    Комментировать
  • Php как проверить два многомерных массива по id и вывести true?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    Сдаётся мне, здесь путаница в терминологии.
    Магический шар мне подсказывает, что ситуация такая. У нас есть два численно индексированных массива, каждый элемент которых представляет собой ассоциативный массив определённого формата. Формат ассоциативных массивов одинаков для всех элементов каждого из численно индексированных массивов.

    Тогда код будет примерно таким:

    foreach ($secondArray as $secondArrayElement) {
        $secondArrayElement = (array)$secondArrayElement;  // вы везде пишете "массив", но, судя по вашему примеру, у вас тут объект, а не массив. Поэтому я сделал явное преобразование в массив на случай если была ошибка в формулировке.
        $doesExistInFirstArray = false;
    
        foreach ($firstArray as $firstArrayElement) {
            if ($firstArrayElement['ID'] == $secondArrayElement['id']) {
                 $doesExistInFirstArray = true;
                 break;
            }
        }
    
        $secondArrayElement['doesExistInFirstArray'] = $doesExistInFirstArray;
    }


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

    Уточните, этого ли вы хотели? Если нет, то постарайтесь разобраться в терминолоии и задать вопрос правильно.
    Сейчас он звучит как полнейшая чушь.
    Ответ написан
    Комментировать
  • Рекомендуете платформа для интернет магазина?

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

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    Шаблоны выносить в отдельные файлы.
    Если тебе нужно весь этот HTML складывать в переменную, то вот тебе волшебная функция:

    function render($part, array $vars=[]) {
        extract($vars);
        ob_start();
        require __DIR__ . "/views/" . $part . ".php"; // путь тут поправь в соответствии с твоими реалиями
        return ob_get_clean();    
    }


    Всё, дальше свои шаблоны можешь складывать в папке /views.
    Итого, в твоем исходном файле будет вот такой код вместо твоей портянки:

    $user_html_entity = render("user_entity", compact(
        "user_id", 
        "user_avatar_link", 
        "user_nickname",
        "user_last_online_datetime",
        "user_initials_info_string",
        "user_location_string"
    ));


    А, твой шаблон будет лежать красиво отдельно и там будет HTML с минимальным количеством PHP для вывода динамически генерируемых данных.

    Вот так примерно:

    <a href="/user/<?= $user_id ?>" class="user" data-id="users___user_link">
        <div class="section_900">
            <img src="<?= $user_avatar_link ?>">
            <div class="no_image_content">
                <p class="nickname"><?= $user_nickname ?></p>
                <p class="online_status"><?= Get_Online_Status_From_Datetime($user_last_online_datetime) ?></p>
                <p class="initials"><?= $user_initials_info_string ?></p>
                <p class="location"><?= $user_location_string ?></p>
            </div>
        </div>
    </a>


    PS Волшебную функцию можно будет использовать и внутри самого шаблона, так что если у тебя будет много кода, который надо будет побить на меньшие кусочки, то и это ты легко сможешь сделать
    Ответ написан
  • Что не так с кодом?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    Выкинуть init()
    Сделать __contstruct. В нём принимать key
    Выкинуть проверки ключа из кода
    Не использовать underscore в названиях функций (вкусовщина, но PSR)
    Функцию перевода сделать не статической.
    В функции перевода никаких данных из $_GET не вытаскивать. Все параметры только принимать. Если нужно что-то из $_GET, то делать это вне этого класса, не забыв санитайзинг и валидацию
    Не использовать устаревший синтаксис array()
    Обязательно выставлять таймаут на ответ внешнего сервиса
    Обрабатывать ошибки если они произошли во время запроса (если сервер вернул 404, например. Или если он не ответил в таймаут)
    json_decode вызывать только с флагом JSON_THROW_ON_ERROR или явно проверять что json распарсился корректно
    Код ответа вытаскивать не из json'а, конечно.
    Валидировать корректность полученных данных перед возвратом (убедиться что все ожидаемые поля на месте и значения в пределах допустимых)
    Ответ написан
    Комментировать
  • Как добавлять свои аватар пользователям сайта через mysql в phpmyadmin?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    Для превращения картинки в код можно воспользоваться онлайн-сервисами. Например, вот: https://www.base64-image.de/
    Дальше этот код можно положить в базу
    Ответ написан
    Комментировать
  • Как при приеме вебхука от апи отсечь дублирующий запрос?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    Ну в файл пишите id-шники обработанных webhook'ов. Или в сессию
    Ответ написан
    Комментировать
  • Как удалить символы и поставить по середине?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    function cleanText(string $text) {
        $cleaned = [];
        
        foreach (str_split($text) as $i=>$letter) {
            if ($letter === "&" || $text[$i-1] === "&") {
                continue;
            }
            
            $cleaned[] = $letter;
        }
        
        return implode("", $cleaned);
    }


    upd: второй вопрос

    function justify(string $someWord, string $otherWord) {
        $spaces = "";
        
        if (strlen($someWord) !== strlen($otherWord)) {
            $diff = abs(mb_strlen($someWord)-mb_strlen($otherWord));
            $offset = ceil($diff/2);
            $spaces = str_repeat(" ", $offset);
        }
        
        if (mb_strlen($someWord) >= mb_strlen($otherWord)) {
            return $someWord . PHP_EOL . $spaces . $otherWord;
        } else {
            return $spaces . $someWord . PHP_EOL . $otherWord;
        }
    }
    Ответ написан
  • Как проверить данные для авторизации через MySQL?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    mysqli_query возвращает false если во время выполнения запроса произошла ошибка. Поэтому, если вы уж пишете в таком стиле, то извольте проверять, что во время выполнения запроса ошибки не произошло. Примерно так:
    $checkUser = mysqli_query($connect, "SELECT * FROM `users` WHERE `email` == '$email' AND `password` == '$password'");
    if ($checkUser  === false) {
        die(mysqli_error($connect));
    }


    После того как вы добавите в код проверку, вы увидите что система ругается на некорректный синтаксис SQL-запроса. Конкретно в вашем случае это использование "==" для сравнения. В MySQL используется одинарное "=" для сравнения.
    После того как вы исправите эту ошибку, код ваш заработает, но он будет очень небезопасным.
    Для того чтобы подставлять значения из php-перемнных в SQL-запрос, используйте подготовленные выражения.

    Более подробно расписано почему не стоит использовать mysqli_num_rows и как пользоваться подготовленными выражениями (информация была скопирована отсюда):

    Это очень хороший вопрос.
    Ответ на него - никак не использовать.

    Да, в mysqli действительно есть специальная функция, которая может сказать, какое количество строк вернул запрос SELECT.
    Традиционно употребляется в двух случаях:

    а) когда это не нужно
    б) когда приводит к катастрофическим последствиям

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

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

    Правильным решением этой задачи будет сделать запрос вида SELECT COUNT(*) FROM .... В этом случае БД сама внутри себя посчитает количество строк (очень быстро) и вернёт только одно число, которое не занимает оперативную память вообще.

    Вот и получается, что функция mysqli_num_rows() является либо вредной, либо бесполезной

    В данном случае надо сначала получить записи из БД
    // БЕЗОПАСНО выполняем запрос
    $stmt = $link->prepare("SELECT * FROM comments WHERE art_id = ?");
    $stmt->bind_param("s", $note_id);
    $stmt->execute();
    // получаем данные
    $result = $stmt->get_result();
    $comments = $result->fetch_all(MYSQLI_ASSOC);


    А после этого уже их выводить
    <?php if ($comments): ?>
        <?php foreach ($comments as $row): ?>
             <?=$row['comment']?><br>
        <?php endforeach ?>
    <?php else: ?>
        Эту запись еще никто не комментировал
    <?php endif ?>


    Как видно, никакой mysqli_num_rows нам не понадобилось
    Ответ написан
    7 комментариев
  • Не могу понять почему не авторизуется на сайте через vk?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    У вас в проблемной строчке очень много операций.
    Разбейте эту строку на несколько отдельных действий, определите, какое из них вызывает ошибку и потом уже отталкивайтесь от этого при решении проблемы.

    Примерно так:
    $queryString = http_build_query($params);
    $decodedQueryString = urldecode($queryString); // Не совсем понимаю, зачем эта операция вообще. Объясните, зачем вы это делаете
    $requestUrl = "https://oauth.vk.com/access_token?{$decodedQueryString}";
    $response = file_get_contents($requestUrl);
    $userInfo = json_decode($response);
    Ответ написан
    8 комментариев
  • Как получить данные из JSON в переменные?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    $json = '{"status":{"timestamp":"2021-05-03T16:47:16.362Z","error_code":0,"error_message":null,"elapsed":370,"credit_count":0,"notice":null},"data":{"2016-10-26T02:39:28.000Z":{"BTC":[1],"USD":[660.28167725,87283944,10525640015.288086]},"2016-10-27T02:39:28.000Z":{"BTC":[1],"USD":[702.39459229,89816296,11200777509.550781]}}}';
    $data = json_decode($json, true);
    
    foreach($data['data'] as $date=>$values) {
        $date = date("Y-m-d H:i:s", strtotime($date));
        $usd = $values['USD'][0] ?? null;
        $usd_two = $values['USD'][1] ?? null;
        $usd_three = $values['USD'][2] ?? null;
        
        // Далее здесь можно вызвать функцию, которая сохранит значения в базу
    }
    Ответ написан
    1 комментарий
  • Как разделить/разбить ответ от базы на несколько массивов?

    Immortal_pony
    @Immortal_pony Куратор тега PHP
    $fromDb = [
        ['id'=>1, 'day'=>2, 'month'=>1],
        ['id'=>2, 'day'=>22, 'month'=>3],
        ['id'=>2, 'day'=>31, 'month'=>2],
        ['id'=>4, 'day'=>12, 'month'=>2],
        ['id'=>5, 'day'=>4, 'month'=>3]
    ];
    
    function groupBy(array $elements, callable $getUniqueKey) {
        $grouped = [];
        
        foreach ($elements as $element) {
            $uniqueKey = $getUniqueKey($element);
            $grouped[$uniqueKey][] = $element;
        }
        
        return $grouped;
    }
    
    $groupedByMonth = groupBy($fromDb, function($row) {
        return $row['month'];
    });
    Ответ написан
    Комментировать