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

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Если поиск в массиве осуществляется через foreach, то грош цена такому массиву.

    Сила массива в том, что доступ к элементу можно осуществлять по индексу, то есть практически моментально. Так что для оптимизации старайтесь делать именно это. То есть обратите внимание на то, какой критерий поиска вы используете, а не что вам нужно извлечь. Ведь при доступе к элементу (который является объектом или структурой), вы и так получите доступ ко всем его свойствам, основное время тратится именно на поиск. Например, если поиск по какому-то уникальному свойству (артикулу, например), то можно сделать ассоциативный массив, ключом которого является именно артикул.

    Конечно, на формирование массива тоже тратится время, какой бы оптимизированный поиск ни был. Поэтому супер большие массивы - тоже признак плохой оптимизации. Не зря же придумали базы данных. А что если в базе не 30 тыс. товаров, а миллиард? Тоже загоните их в массив? Надеюсь, что нет, а вместо этого будете пользоваться средствами поиска самой базы данных.

    Но если всё же оптимизировать создание массива наравне с последующим поиском по нему, то нужно будет углубиться в суть задачи, а также изучить, какие вообще есть структуры данных в PHP, какие у них плюсы и минусы, как они устроены на низком уровне, и как на их основе сделать более совершенные структуры данных (конкретно для вашей задачи).
    Ответ написан
    3 комментария
  • Почему javascript и php сообщают мне неправильное время?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Документацию по Date.now() читали?

    Метод Date.now() возвращает количество миллисекунд, прошедших с 1 января 1970 года 00:00:00 по UTC.

    Гуглим, что такое UTC.

    Соответственно, для date() можно заюзать date_default_timezone_set()
    Ответ написан
    Комментировать
  • Как определяют реальный IP адрес запроса?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Прокси может передавать IP адрес. Прокси, которые не передают IP, называются анонимными (условно, конечно же).

    А вообще другой сайт может и не знает реальный IP адрес, а просто видит, что запрос идёт именно с прокси. То есть сайт знает список прокси, и видит, что IP запроса совпадает с одним из прокси. Либо сайт сканирует конкретные или все порты на IP запроса с целью обнаружить там прокси. Как вариант)

    И ещё сайт может банить не за прокси, а за сам факт париснга. Как он обнаруживает парсинг - это совсем другая история.
    Ответ написан
    5 комментариев
  • Как сделать прогресс бар с отрезками?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Для поиска ошибок в существующем коде нужно заняться его отладкой.
    Если совсем не знаешь, с чего начать, то начни с самого понятия отладка.
    Ну или жди телепатов.
    Ответ написан
    2 комментария
  • Как сделать все возможные комбинации?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Вложенный цикл, очевидно.
    $arr = [1, 2, 3];
    $len = count($arr);
    
    $new_arr = [];
    
    for($i=0; $i<$len; $i++) {
        for($j=0; $j<$len; $j++) {
            $new_arr[] = [$arr[$i],$arr[$j]];
        }
    }
    
    var_dump($new_arr);
    Ответ написан
    1 комментарий
  • Как сохранить значение кнопки после обновления страницы?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    localStorage

    Можно локально (т.е. в браузере) хранить информацию, что купон уже активирован. И не нужно будет лишний раз беспокоить БД.
    Ответ написан
    7 комментариев
  • Как сохранять информацию о нажатии на кнопку на сервере?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Я так понял надо взаимодейстовать с сервером и там сохранять информацию

    Да. В момент нажатия отправить запрос на сервер и отложить реакцию до прихода ответа от сервера. На сервере же будет обычная очередность: Петя, Вася, Петя, Вася и т.д. Таким образом, какие бы ни были пинги, очерёдность будет довольно строгая. А если до сервера не удалось достучаться, то можно в качестве реакции что-то типа Radnom(Петя,Вася).
    Ответ написан
  • Как при переадресации на страницу авторизации запомнить изначальный запрос?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    В куках можно запомнить.
    Ответ написан
    Комментировать
  • Как преобразовать число в строку?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    $soldprice = 123;
    echo(" x " . $soldprice);
    Ответ написан
    3 комментария
  • Как слить несколько массивов с одинаковыми ключами, но выбрать самые большие значения?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Очень просто.

    Для каждого массива нужно найти максимальное значение (и соответствующий ключ). Одновременно с этим нужно формировать итоговый массив, добавляя туда найденные максимальные значения.

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

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Можно воспользоваться функцией hash_file().
    Надеюсь, SHA-256 вам будет достаточно.
    Ответ написан
    4 комментария
  • Почему переменная себя так странно ведет?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Это не странно.
    Просто по факту в переменной не "true" и не "false".
    (это ответ на вопрос)

    Попробуйте: echo($hasInstalled);
    Также попробуйте: echo(strlen($hasInstalled));
    (это отладка вашего кода)
    Ответ написан
    5 комментариев
  • Какое создать регулярное выражение?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Главное, чтобы было четыре секции между двоеточиями.

    Если это главное (и единственное) требование, то сами секции задаются как раз этим двоеточием. Поэтому банальное (но пока что ошибочное) рег. выражение:
    .*:.*:.*:.*
    Двоеточие в этом выражении соответствует двоеточию в исходной строке. Поэтому строка a:b:c будет не валидной - слишком мало секций. Выражение .* означает любое количество любых символов. Ошибка здесь в том, что любым символом также может быть двоеточие, поэтому это регулярное выражение разрешает более, чем 4 секции. Чтобы исправить это, нужно запретить символ двоеточия в последовательности любых символов. Выражение [^:] означает любой символ, кроме двоеточия:
    [^:]*:[^:]*:[^:]*:[^:]*

    Остался последний штрих. Пока что это рег. выражение всё ещё разрешает более одной секции, потому что поиск можно начинать с середины строки и заканчивать, не доходя до конца. Поэтому если подсунуть строку a:b:c:d:e:f выражение убедится, что подстрока a:b:c:d соответствует рег. выражению, а значит валидна. Чтобы исправить это, нужно указать, что проверку нужно начинать с самого начала строки и дойти до самого конца строки. То есть рассматривать строку целиком, а не по частям. Это делается с помощью указателей позиций. Символ ^ (в начале) означает начало строки, а символ $ (в конце) означает конец строки:
    ^[^:]*:[^:]*:[^:]*:[^:]*$

    Собственно, это и есть правильный ответ в общем виде на вопрос с главным требованием. Секции ровно четыре и они разделены двоеточием. В каждой секции двоеточие запрещено. Выражение [^:]* означает любое количество любых символов, кроме двоеточия, что нам и нужно.

    Однако данное выражение можно немного улучшить, в зависимости от дополнительных требований. Например, нас может не устроить, что для каждой секции считается валидным любое количество символов, даже нулевое. То есть строка a:b::c тоже будет валидной. Для этого нужно сменить квантификатор * на какой-либо другой. Например, можно сменить на +, который означает любое количество вхождений (символа) больше нуля, то есть 1 и более:
    ^[^:]+:[^:]+:[^:]+:[^:]+$

    Далее, может быть желательно выделить группы, чтобы рег. выражение не только проверяло исходную строку на соответствие шаблону ip:port:user:pass, но и извлекало эти самые переменные. Группы задаются просто скобками. Очевидно, что разделители и указатели позиций в группы не входят:
    ^([^:]+):([^:]+):([^:]+):([^:]+)$

    Далее можно вспомнить, что параметр port может содержать лишь арабские цифры. В регулярных выражениях \d (или [0-9]) означает любую цифру. Так что легко вносим улучшение:
    ^([^:]+):(\d+):([^:]+):([^:]+)$
    Хотя постойте-ка. Это ещё не всё с параметром port. Ведь абсолютное любое число, состоящее из цифр, нас не устроит. Как минимум, порт не может быть больше 65535, поэтому любое число выше считается ошибкой. В принципе, на данном этапе можно не заморачиваться и просто проигнорировать это требование, а реально проверить его позже кодом типа такого: $post < 65356, но в качестве примера можно всё же ограничить количество цифр от 2 до 5:
    ^([^:]+):(\d{2,5}):([^:]+):([^:]+)$
    Квантификатор {2,5} означает, что количество вхождений (цифр) должно быть не менее 2 и не более 5, иначе секция будет считаться не валидной, а значит и вся строка тоже.

    Далее, можем также сделать более строгое условие для параметра ip. Для простоты будем считать, что разрешён только IPv4, а IPv6 нельзя использовать. Тогда условием будет 4 цифры, разделённые точкой. Каждая цифра от 1 до 3 символов:
    \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}
    Ой, ошибочка вышла! Дело в том, что символ . является квантификатором. И чтобы рег. выражению сказать, что нам нужен сам символ точки, нужно его экранировать: \.
    В результате полностью рег. выражение получается таким:
    ^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d{2,5}):([^:]+):([^:]+)$


    Да, получился монстр. Но нет предела совершенству.

    Правда, на этом этапе улучшать проверки уже не целесообразно. Далее уже кодом PHP можно проверить более строги условия. Например, сейчас в качестве ip будет валидной строка 300.400.500.600. Ведь всё сходится - 4 числа, разделённые точкой, в каждом от 1 до 3 цифр. Поэтому нужно либо более монструозное выражение лепить, либо кодом проверять, либо отдать на откуп сетевым ошибкам подключения - зависит от конкретного приложения и конкретной задачи.

    Рег. выражения не заточены на сравнение чисел, например. Чтобы проверить, что число находится в диапазоне от 0 до 255, придётся лепить что-то такое:
    (?:\d\d?|[0-1]\d\d|2[0-4]\d|25[0-5])
    То есть это вообще поразрядная проверка. Глупо. Проще это делать кодом, если это действительно нужно.

    На данном же этапе имеет смысл проверять лишь то, подо что заточены регулярные выражения. Например, можно ограничить класс символов, которые входят в user и в pass. Например, в пароле можно разрешить только латинские символы и цифры, а также ограничит длину: пароль не может быть меньше 6 и не может быть больше 32 символов:
    [a-z0-9]{6,32}
    (просто пример)

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

    dollar
    @dollar
    Делай добро и бросай его в воду.
    $noUp[$i]
    Ответ написан
    Комментировать
  • Есть и разница между разделителями | и +?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    1 + 2 == 3
    1 | 2 == 3

    но
    1 + 3 == 4
    1 | 3 == 3

    ибо 1 | 3 - это поразрядное ИЛИ, то есть берём в двоичной 01 и 11, и в результате ставим те разряды в 1, для которых у хотя бы одного аргумента на том же месте стоит 1, и получается снова 11 (т.е. 3 в десятичной).
    ваш пример
    Можете проверить значение константы как-то так: echo(XHPROF_FLAGS_CPU);
    Обычно флаги задаются степенями двойки: 1, 2, 4, 8, 16 и т.д., поэтому их можно складывать через + и обычно это не является ошибкой, но по-хорошему правильнее использовать | для флагов.
    Ответ написан
    2 комментария
  • Как проверить заголовок?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Проверить так:
    /[g-z]|[a-f]{3,}/i
    Ответ написан
    1 комментарий
  • Как равномерно распределить массивы между пользователями?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Как-то так:
    spoiler
    //v1.0
    function arr_num($user_id) {
      static $N = 10;
      return $user_id % $N;
    }

    Когда количество списков снова возрастёт, чтобы назначенные не менялись:
    spoiler
    (при условии, что user_id задан через auto_increment)
    //v2.0
    function arr_num($user_id) {
      static $N = 100;
      if ($user_id < 556780960) { //old algorithm v1.0
        return $user_id % 10;
      }
      return $user_id % $N;
    }
    Хотя будет не совсем равномерно в целом, но дальше уже начинается больше математика, чем программирование.
    Ответ написан
    Комментировать
  • Каким регулярным выражением можно найти знак ")"?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Нужно экранировать его:
    \)
    spoiler
    $re = '/\)/';
    $str = 'Hi (all)!';
    
    preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
    
    // Print the entire match result
    var_dump($matches);

    https://regex101.com/r/tRw8Ug/2
    Ответ написан
    Комментировать
  • Как найти в тексте слова, начинающиеся с большой буквы, которые стоят в начале и не в начале предложения?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    В два этапа.

    Сначала разбить текст на предложения.
    Затем разбить каждое предложение на слова.

    Как именно это делать, зависит от допущений, на которые вы готовы. Например, обязателен ли пробел после точки (между предложениями) и т.д.
    Ответ написан
    Комментировать
  • Как задать условие?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Немного сумбурно и странно звучит вопрос.

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

    В таком случае желание не показывать блок в коде противоречит условию задачи. Ведь выводить или не выводить мы узнаём позже, причём на стороне клиента с помощью js. Так что в коде блок должен присутствовать обязательно.

    Получается, что задачу можно переформулировать так: не показывать блок div до тех пор, пока не будет обнаружено изображение.

    Делается это, очевидно, путём изначальной невидимости блока div.
    .block {display:none}

    Далее скриптом отслеживаем появление изображения, и меняем свойство невидимости у блока.
    Ответ написан
    1 комментарий