Ответы пользователя по тегу PHP
  • Как проверить целый тип данных в php?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Используйте filter_var() и фильтр валидации FILTER_VALIDATE_INT:

    $input = "22";
    $test = filter_var( $input, FILTER_VALIDATE_INT);
    if( $test === false) throw new Exception("не целое что-то");
    
    $test // содержит точно целое число

    По скорости 1E6 итераций разных выражений у меня 1.92 секунды против 3.15 секунд с регулярками. Тест проводил так:
    $tests = [
        '5qwerty'       => false,
        '55'            => 55,
        '1234567890'    => 1234567890,
        '123Z456'       => false,
        'A10'           => false,
    ];
    
    $start = microtime(true);
    for ($i = 0; $i <= 1E6; $i++) {
        foreach( $tests as $test => $result) {
            if( $result !== filter_var( $test, FILTER_VALIDATE_INT)) throw new Exception("Mismatch");
    //      if( !!preg_match('/^\d+$/', $test) !== !!$result) throw new Exception("Mismatch");;
        }
    }
    echo (microtime(true) - $start) . PHP_EOL;
    Ответ написан
    Комментировать
  • Как создать таблицу из массива кратно ключу?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    $arr = array (1, 2, 3, 4, 5, 6, 7, 8, 9);
    $len = 3; // длина строки
    
    // из массива данных для одной строки делает разметку строки
    function make_row( $arr) {
      return '<tr>' . implode( '', array_map( 'make_td', $arr)) . '</tr>';
    }
    
    // из данных одной ячейки делает разметку ячейки
    function make_td( $td) { return '<td>' . $td . '</td>'; } 
    
    $rows = array_chunk( $arr, $len); // массив массивов по 3 эл.
    $rowsHtml = array_map( 'make_row', $rows); // массив строк
    $tableHtml = '<table>' . implode( "\n", $rowsHtml) . '</table>';
    
    echo $tableHtml;
    Ответ написан
    3 комментария
  • Возможно ли автоматически парсить информацию не через cron?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Google Alerts можно настроить, чтобы вам приходило оповещение о новых материалах на сайте.
    Ответ написан
    Комментировать
  • Как показать отсчет таймера одинаковым для всех?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Нужно, чтобы клиент максимально точно «знал», сколько сейчас времени на сервере. Для этого можно несколько раз послать запрос на сервер, и предположить, что время ответа сервера лежит точно посередине между отправкой запроса и получением ответа. Примерно так работает NTP – протокол сетевого времени.

    Второе предположение, что ход собственных часов точен: 1 секунда на клиенте и на сервере точно равны.

    На сервере разместить простейший скрипт, который возвращает время с миллисекундами до События:
    // getTimeTill.php
    $deadline = strtotime("2017-07-01 03:00:00");
    echo round( 1000 * $deadline - 1000 * microtime(true)); // в миллисекундах

    На клиенте в JS надо засечь время, выполнить ajax запрос, получить ответ, и считать, что полученное число микросекунд оставалось до события половину разницы назад:
    var start = (new Date).getTime();
    $.get("getTimeTill.php", function( ms ){
      var bias = Math.round(((new Date).getTime() - start) / 2);
      var remains = ms + bias; // сколько остаётся микросекунд до события на данный момент
      var deadline = (new Date).getTime() + remains; // локальное время События
      // можно запускать таймер, который раз в 200 ms будет обновлять время до События
      var el = document.getElementById("timer");
      window.setInterval( function(){
        var remains = Math.floor((deadline - (new Date).getTime())/1000);
        var H = Math.floor( remains / 3600);
        remains -= 3600 * H;
        H = ( '0' + H ).substr(-2);
        var M = Math.floor( remains / 60);
        remains -= 60 * M;
        M = ( '0' + M ).substr(-2);
        var S = ( '0' + remains ).substr(-2);
        timer.innerText = "" + H + ":" + M + ":" + S;
      }, 200);
    });

    Такие запросы можно выполнять неоднократно, каждый раз уточняя таймер отсчёта на клиенте.
    Ответ написан
    1 комментарий
  • Простой код PHP, где ошибка?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Надо настроить веб-сервер, чтобы все запросы направлял на ваш index.php

    Сейчас запрос не доходит до вашего скрипта, и 404 возвращает сам веб-сервер.
    Ответ написан
    1 комментарий
  • Как максимально перемешать строки?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Каждый IP адрес это 32-битное целое.

    Можно отсортировать по обратному порядку бит в числе – это здорово раскидает соседние адреса.

    Понадобятся три функции:
    function ip2n( $ip ) { // строку ip перевести в целое
    	$ipa = explode('.', $ip);
    	return $ipa[0]<<24 | $ipa[1] << 16 | $ipa[2] << 8 | $ipa[3];
    }
    
    function n2ip( $n ) { // целое перевести в строку ip
    	return implode('.', array(
    		$n >> 24 & 0xFF,
    		$n >> 16 & 0xFF,
    		$n >> 8  & 0xFF,
    		$n & 0xFF
    	));
    }
    
    function bitreverse( $n ) { // развернуть порядок бит в 32-битном целом
    	return bindec( strrev( sprintf( '%032b', $n)));
    }


    Теперь остаётся загрузить ваши ip в массив, и прогнать через ip2n, bitreverse, обычную сортировку целых по возрастанию, bitreverse и n2ip. Пример:
    $ips = array(
    	'192.168.1.15',
    	'192.168.1.16',
    	'192.168.1.17',
    	'95.181.217.91',
    	'95.181.217.96',
    	'95.181.217.97',
    	'91.216.3.90',
    	'91.216.3.91',
    	'91.216.3.99',
    	'5.62.157.78',
    	'5.62.157.84',
    	'5.62.157.87',
    );
    
    $ips = array_map( 'ip2n', $ips);
    $ips = array_map( 'bitreverse', $ips);
    sort( $ips, SORT_NUMERIC);
    $ips = array_map( 'bitreverse', $ips);
    $ips = array_map( 'n2ip', $ips);
    
    print_r($ips);
    /* Array
    (
        [0] => 95.181.217.96
        [1] => 192.168.1.16
        [2] => 5.62.157.84
        [3] => 91.216.3.90
        [4] => 5.62.157.78
        [5] => 95.181.217.97
        [6] => 192.168.1.17
        [7] => 91.216.3.99
        [8] => 95.181.217.91
        [9] => 91.216.3.91
        [10] => 5.62.157.87
        [11] => 192.168.1.15
    ) */
    Ответ написан
    2 комментария
  • Как обеспечить безопасность хранения ключа API?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Обращаться к файлам на уровень выше обычно можно, и так и делают: папка проекта и в неё подпапка, корень веб сайта:
    /var/www/Project/
      .secret_data.php
      public_html/
        index.php  <-- отсюда подключается "../.secret_data.php"


    И параметры доступа к БД и ключи API стоит хранить в таком месте. Ещё часто их значения подгружают в массив окружения $_ENV и $_SERVER при выполнении, и оттуда берут при необходимости. Грубо пример .secret_data.php:
    $params = array(
      'API_KEY' => '3pyWtP7KYVheJWkftdchJLWhwUcK8Rdw',
      'DB_HOST' => '127.0.0.1',
      'DB_USER' => 'root',
      'DB_PASS' => 'secret',
    );
    $_ENV = array_merge( $_ENV, $params);
    $_SERVER = array_merge( $_SERVER, $params);


    Распространённое решение – использовать пакет vlucas/phpdotenv, который загружает «секретные» данные из файла .env
    Ответ написан
  • Как заставить сосчитать значение выражения?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    eval() – но это крайне небезопасно, т.к. исполняется любой код.

    Хотя бы проверяйте перед eval(), что в строке только цифры и -, +, *, /. Если есть что-то ещё – не выполняйте.
    Ответ написан
  • Как загрузить и обрезать фото?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Для начала:
    1. смотрите эту строчку: if (@imagejpeg($virtual_image, $path2, 90)) { – квадратная картинка должна сохраниться в путь $path2, но его значение нигде не определено;
    2. функция createThumb() объявлена, но нигде не вызывается;
    Ответ написан
  • Можно ли заблокировать доступ к сайту человеку по его ip?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Имя «ppp109-252-68-14...» говорит о том, что этот адрес из пула динамических IP адресов. Т.е. сегодня этот пользователь, завтра другой с этого же адреса. Таким образом, вряд ли бан по ip имеет смысл.

    Проще вычистить из системы оценок все оценки ниже 3, ведь вас это интересует в конечном итоге? И проставить побольше пятёрок самим себе ) Объективность? Нет, не слышал.
    Ответ написан
    4 комментария
  • Как подменить значения value на мое значения?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Неправильно решить проблему можно примерно так:

    <?php
    $dict = array(
    	'non_country' => "Не выбрано",
    	'austria' => "Австрия",
    	'austria' => "Австрия",
    	'belgia' => "Бельгия",
    	'bolgaria' => "Болгария",
    	'vengry' => "Венгрия",
    	'germany' => "Германия",
    	'grecee' => "Греция",
    	'daniya' => "Дания",
    	'ispania' => "Испания",
    	'italy' => "Италия",
    	'kitay' => "Китай",
    	'latviya' => "Латвия",
    	'litva' => "Литва",
    	'malta' => "Мальта",
    	'niderlandy' => "Нидерланды",
    	'norvegiya' => "Норвегия",
    	'polsa' => "Польша",
    	'portugal' => "Португалия",
    	'singapur' => "Сингапур",
    	'slovakiya' => "Словакия",
    	'sloveniya' => "Словения",
    	'usa' => "США",
    	'finland' => "Финляндия",
    	'france' => "Франция",
    	'chech' => "Чехия",
    	'shvecariya' => "Швейцария",
    	'sveciya' => "Швеция",
    	'estoniya' => "Эстония"
    );
    
    function toName($key) {
    	return isset( $dict[$key]) ? $dict[$key] : $key;
    }
    
    if( isset( $_POST["country"]) {
    	$names = array_map('toName', $_POST['country']);
    	$email_content .= join(', ', $names);
    }
    Ответ написан
    Комментировать
  • Как запускать по очереди крон?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Очередь задач на PHP можно реализовать разными средствами. Например, сервер и клиенты Gearman («пушка по воробьям» для вашей задачи) или Queues в фреймворке Laravel.

    По кнопке «Запустить» просто сохраняется введённая ссылка. А в фоне постоянно работает процесс (или несколько), ожидающий задачи и обрабатывающий их. Этот «рабочий» процесс, запущенный из командной строки, может выполняться сколь угодно долго. Выполнив одно задание он тут же переходит в режим ожидания следующего. Уже есть следующее – сразу начинает выполняться. И так далее.

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

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Распараллелить вычисления в PHP? Маэстро знает толк.. в php.

    Смотреть можно в сторону очередей задач: запускаете в работу задания, работает несколько параллельных процессов-рабочих, которые хватаются их выполнять. Ждете, пока будут готовы все три. Например, см. Gearman.
    Ответ написан
    4 комментария
  • PHP Голосование для всех. Какая лучше защита от повторного голосования?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Никак не показывать при повторном голосовании, что голос НЕ учтен. Пусть накрутчики и «случайно» голосующие повторно полагают, что их голос засчитан. Даже сохраняйте такие голоса в БД, но помечайте как фейковые. А затем раз в сутки их выбрасывайте из общих показателей. Можно даже наоборот – полноценно учитывать фейковые голоса, но накидывать так же голоса прочим вариантам, нивелируя накрутку.

    Это не даст легкого способа злодеям наладить механизм накрутки. Вслепую им будет труднее.

    А в остальном – все те же, EverCookie и FingerprintJS 2. Подробнее почитайте хороший материал на Хабре: отпечаток браузера и т.п.
    Ответ написан
    Комментировать
  • Реализовать очередь на php?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    • Gearman
    • Laravel и его очередь задач (Queue)
    • собственная реализация на Redis


    p.s. вставку в базу попробуйте реализовать, минуя PHP: например, модулем nginx сразу вставлять в Postgres или Redis.
    Ответ написан
    Комментировать
  • Как разделить динамический вывод элементов на группы?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    • array_chunk() бьёт массив на группы по N элеметов.
    • array_map() применяет функцию к каждому из элементов.
    $cities = array('London', 'NY', 'LE', 'Rome');
    
    function wrapRow( $row) { return '<div>' . join(", ", $row) . '</div>'; }
    
    $rows = array_chunk( $cities, 3);
    $html = join( array_map("wrapRow", $rows));
    
    var_dump($html); // "<div>London, NY, LE</div><div>Rome</div>"
    Ответ написан
    Комментировать
  • Как лучше выводить строки с несколькими переменными?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    // 3-й вариант
    printf( "Format: %s. Config: %s. System (OS): %s.\n\n", 
      $format,
      $config->path,
      $os
    );


    А воообще, «вам шашечки, или ехать?!» и «работает – не трожь!»

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

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    скачивать изображения всё-таки придётся – хотя бы по одному, во временную папку, чтобы загрузить в ВК и удалить у себя по окончании загрузки.

    Что касается непосредственно загрузки, можно использовать cURL и его CURLFile, или, удобнее, Guzzle. Например:
    $client = new \GuzzleHttp\Client;
    		$resource = fopen( $tmpfile, 'r');
    		$response = $client->request(
    			'POST',
    			$upload_url,
    			[
    				'multipart' => [
    					[
    						'name'	 => 'file',
    						'contents' => $resource
    					]
    				]
    			]
    		);
    		
    		$uploadResult = json_decode( $response->getBody());
    Ответ написан
    Комментировать