Ответы пользователя по тегу PHP
  • Как трансформировать код из 1 вида в другой?

    @ksnk
    Отредактировал немного, сейчас работает лучше, но в принципе - наверное лучше в класс перетащить, а то 3 анонимные функции как-то криво начинают выглядеть.
    <?php
    
    $source = <<<'code'
    <?php
    
    $name = 'anon';
    echo '<h2>';
    echo 'Number is: ';
    echo count(["1","2","3"]);
    echo '</h2>';
    echo 'CHECK
    
    ';
    echo 1 + 3 . '-'. 4 . '=' . 0;
    echo '
    
    ';
    echo '<h2>';
    echo 'Olololo';
    echo '</h2>';
    echo '
    
    ';
    echo '<h3>';
    echo 'QWErty';
    echo '</h3>';
    echo '
    
    
    ';
    echo '<h2>';
    echo 'Hello, ';
    echo $name;
    echo '</h2>';
    echo '
    
    ';
    foreach ([1,2,3] as $item) {
    echo '
        ';
    echo '<h2>';
    echo 'Number is: ';
    echo $item;
    echo '</h2>';
    echo '
    ';
    }
    code;
    
    $tokens = token_get_all($source);
    $last_token=false;
    
    $getnext=function() use (&$tokens, &$last_token){
      $token=array_shift($tokens);
      if(is_null($token)) return false;
      if(is_array($token)){
        $last_token= token_name($token[0]);
        return  $token[1];
      } else {
        $last_token='';
          return  $token;
      }
    };
    
    $getbracket=function($bracket) use (&$tokens,$getnext,&$last_token){
    	$stack=[]; $buf=$bracket;
    	
    	if($bracket=='[') array_unshift($stack,']');
    	if($bracket=='(') array_unshift($stack,')');
    	while(false!==($x=$getnext())){
    		$buf.=$x;
    		if($x==$stack[0]){
    			array_shift($stack);
    			if(count($stack)==0) break;
    		}
    		if($x=='(') array_unshift($stack,')');
    		if($x=='{') array_unshift($stack,'}');
    		if($x=='[') array_unshift($stack,']');
    	}
    	return $buf;
    };
    
    $getecho=function() use (&$tokens,$getnext,$getbracket,&$last_token){
      $buf='';
      $buf2='';
      $waitecho=false;
      while(false!==($x=$getnext())){
      	//echo '{'.$last_token.' '.$x.'}';
        if($last_token==='' && $x==';'){
          $waitecho=true;
          $buf2.=$x;
        } elseif($last_token==='T_ECHO' && $waitecho){ // склеиваем
          $waitecho=false;
          $buf.=',';$buf2='';
        } elseif($last_token==='T_WHITESPACE' && $waitecho){ 
          $buf2.=$x;
        } else if($waitecho){
          return $buf.$buf2.$x;
        } else if($last_token==='T_CONSTANT_ENCAPSED_STRING') {// склеиваем константные строки с одинаковыми кавычками
          $s=$x[0];
          $y = preg_replace('~'.preg_quote($s,"~'").'\s*[\.\,]\s*$~', '', $buf, 1, $count);
          if($count>0)
             $buf=$y.substr($x,1);
          else
            $buf.=$x;
        } else if($last_token==='' && in_array($x,['[','('])) {
        	$buf.=$getbracket($x);
        } else {
          $buf.=$x;
        }
      };
      return '';
    };
    
    while(false!==($x=$getnext())) {
      echo $x;
      if($last_token=='T_ECHO'){
        echo $getecho();
      }
    }
    ?>


    <?php
    
    $name = 'anon';
    echo '<h2>Number is: ', count(["1","2","3"]), '</h2>CHECK
    
    ', 1 + 3 . '-'. 4 . '=' . 0, '
    
    <h2>Olololo</h2>
    
    <h3>QWErty</h3>
    
    
    <h2>Hello, ', $name, '</h2>
    
    ';
    foreach ([1,2,3] as $item) {
    echo '
        <h2>Number is: ', $item, '</h2>
    ';
    }
    Ответ написан
  • Как сделать авторизацию по ссылке для фида?

    @ksnk
    Вот упрощенный пример. Пароль-пользователь указан в файле. Каталог для выгрузки файлов - там же.

    <?php
    
    if (!isset($_SERVER['PHP_AUTH_USER'])) {
        header('WWW-Authenticate: Basic realm="My Realm"');
        header('HTTP/1.0 401 Unauthorized');
        echo 'Authentification required.';
        exit;
    } else {
        // config!
        $password='test';
        $user='test';
        $upload_dir=$_SERVER['DOCUMENT_ROOT'].'/tmp/';
        //
    
        if($_SERVER['PHP_AUTH_USER']!=$user ||$_SERVER['PHP_AUTH_USER']!=$password){
            echo 'No user found, sorry.';
            exit;
        }
    
        $filename=$_SERVER['QUERY_STRING'];
        if(!is_readable($upload_dir.$filename)){
            echo 'No file found, sorry.';
            exit;
        }
    
        header('Content-type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($upload_dir.$filename));
        readfile($upload_dir.$filename);
    }

    Использование

    https://test:test@site/file.php?filetoupload.txt
    Ответ написан
    Комментировать
  • Строка из БД как условие сравнения в if?

    @ksnk
    У меня где-то использовался `язык фильтров` - строка с условиями, которую удобно вписывать в область фильтра в столбик таблицы с данными. Постим на сервер - получаем фильтрованное.
    Сама строка условий выглядит примерно так
    count=2,<2;count=3,<300,>44
    условия соединяются запятой, по AND, точкой с запятой - по OR, у OR более низкий приоритет. Операция сравнения соединяет 2 операнда, если один из операндов пустой - берется "сравниваемое значение", если число - то число, иначе ищем во внешних "данных".
    Если записать строку на php - будет что-то вроде
    $current=45; // значение, которое сравниваем
    $data=['count'=>3]; // внешние данные
    if( ($data['count']==2 && $current<2) || ($data['count']==3 &&$current>44 && $current<300)){
        // ...
    }

    Удобно в языке то, что парсер его компактен и легко допиливается напильником по месту.
    function evaluate($current,$cond,$data=[]){
        $res=false;
        foreach(explode(';',$cond) as $or){ //or
            foreach(explode(',',$or) as $and) { //and
                if(preg_match('/^(.*?)(<=|>=|<|>|=)(.*?)$/',$and,$m)){
                    $a=trim($m[1]);$b=trim($m[3]);
                    if(empty($a)) $a=$current;
                    else if(is_numeric($a)) $a=0+$a;
                    else if(isset($data[$a])) $a=$data[$a];
                    else {
                        $res=false; break;
                    }
                    if(empty($b)) $b=$current;
                    else if(is_numeric($b)) $b=0+$b;
                    else if(isset($data[$b])) $b=$data[$b];
                    else {
                        $res=false; break;
                    }
                    if($m[2]=='<=') $res=$a<=$b;
                    else if($m[2]=='>=') $res=$a>=$b;
                    else if($m[2]=='>') $res=$a>$b;
                    else if($m[2]=='<') $res=$a<$b;
                    else if($m[2]=='=') $res=$a==$b;
                } else {
                    $res=false;
                    //throw new \Exception('Некорректное условие в строке '.$and)
                }
                if(!$res) break; // выход по AND
            }
            if($res) break; // выход по OR
        }
        return $res;
    }
    
    $data=['count'=>3];
    
    var_dump(true===evaluate(45,'count=2,<2;count=3,<300,>44', $data));
    var_dump(true===evaluate(1,'<2'));
    var_dump(true===evaluate(1,'>3;<2,>1;<2'));
    Ответ написан
    1 комментарий
  • Как подписать значение по ГОСТ Р 34.10-2012 256?

    @ksnk
    Ответ написан
    Комментировать
  • Как вывести ответы на анкету каждого пользователя на отдельной странице (ответы читаются из файла)?

    @ksnk
    Сохраняй результаты не в txt файл, а в php. Что нибудь такое, при сохранении
    $results_file='results.php';
    $result=include_once($results_file);
    $result[$current_user_id]=['post'=>$_POST, 'time'=>time()];
    file_put_contents($results_file, '<'."?php\nreturn ".var_export($result,true).';')

    Проверку параметров и навороты - по вкусу
    При выводе включаем то же файл и выводит заполненную нужным юзером анкету.

    Ну и начальный results.php
    <?php
    return [];
    Ответ написан
    Комментировать
  • Как ускорить чтение большого архива gz?

    @ksnk
    Читать нужно не по строкам, а блоками, килобайт по 40. Просто проверь - чтение блоками всего файла или чтение построчное gzgets. Вот искать в таких блоках сложнее - нужно гарантировать что найденный кусок не попадет на границу буфера чтения. Для этого, можно последнюю "строку" блока сохранять и копировать в следующий блок.
    Читать загзипованые файлы удобнее, imho, обычными файловыми операциями fread, feof вот только открывать его придется gzopen. Как нибудь так...
    if (preg_match('/\.gz$/', $name)) {
                    $_handle = fopen($name, "rb");
                    fseek($_handle, filesize($name) - 4);
                    $x = unpack("L", fread($_handle, 4));
                    $this->finish = $x[1];
                    fclose($_handle);
                    $handle = gzopen(
                        $handle, 'r'
                    );
                } else {
                    $this->finish = filesize($name);
                    $handle = fopen($name, 'r');
                }
    Ответ написан
  • Как создать обственные BB коды на сайт или форум?

    @ksnk
    Простейший вариант - заменять [CODE] на < pre > и закрывающий [/CODE] на < /pre>. Это не то, что нужно в этом месте ? Чтобы не задумываться о непарных тегах - можно менять регуляркой
    $text=preg_replace('~\[CODE\](.*?)\[/CODE\]~si', '<pre>$1</pre>',$text);

    Если, внезапно, захочется что-то более навороченного - можно посмотреть ответ nokimaro
    Ответ написан
    Комментировать
  • Как скрыть конец ссылки в адресной строке?

    @ksnk
    Тебе , вероятно, нужно не скрыть конец адресной строки, а выкинуть уже ненужный параметр select ?
    Что нибудь этакое, если в query_string действительно query_string, а не что-то еще
    $query=[];
    parse_str(parse_url($query_string, PHP_URL_QUERY),$query_array);
    unset($query_array['select']);
    echo (!empty($query_array)?'?':'').http_build_query($query_array);
    Ответ написан
    Комментировать
  • Как расшифровать gzip архив из file_get_contents?

    @ksnk
    В таком случае удобнее открывать гзипы с помошью curl. Если поставить параметр CURLOPT_ENCODING = 'gzip', то передаваемый в гзипе контент сам распакуется. если надо.
    function getcontents($url){
        if(filter_var($url,FILTER_VALIDATE_URL)) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
            // ssl?
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
            $output = curl_exec($ch);
            curl_close($ch);
            return $output;
        }
        return file_get_contents($url);
    }
    
    
     echo getcontents('https://www.rusprofile.ru/id/11597949');
    Ответ написан
    Комментировать
  • Как сделать регистронезависимую замену?

    @ksnk
    В регулярках есть глобальные и локальные флаги.
    $text = 'JA Ja jA ja';
    $text = preg_replace('/J(?i:a)/', 'Я', $text);
    $text = preg_replace('/j(?i:a)/', 'я', $text);
    Ответ написан
    1 комментарий
  • Какая кодировка данных крякозябр?

    @ksnk
    Нужно добавить
    curl_setopt($ch, CURLOPT_ENCODING ,"gzip")
    Если ответ внезапно перестанет быть зазипованным, то можно погрозить пальчиком хозяину сайта за то, что он посылает зипованный ответ не получив разрешеющих это заголовков... А можно жить так.
    Если не поможет - распаковать как нибудь вручную...
    Ответ написан
    Комментировать
  • Как получить текущий месяц на эстонском языке?

    @ksnk
    В вашем случае - что-то с локалью. Возможно, нужно et_EE.utf8 указать. Но проблема может быть шире и грустнее.
    Для русского языка все равно приходится пользоваться словарной подстановкой месяца. Просто потому, что нужно вывести "1 января", к примеру, а форматированное название месяца выводится "1 Январь". Так что все вручную...
    str_replace(
                array('january','february','march','april','may','june','july',
                    'august','september','october','november','december'),
                array('января','февраля','марта','апреля','мая','июня','июля',
                    'августа','сентября','октября','ноября','декабря'),
                strtolower(date('j F, Y г.',
                    $daystr)));
    и локаль аглицкая, конечно...
    Возможно , для эстонского что-то такое будет тоже применимо...
    Ответ написан
    Комментировать
  • Как обрезать строку?

    @ksnk
    json_decode("{\"button\":\"\\\/-28484-2.1 здесь\"}")->button
    Ответ написан
    Комментировать
  • Почему обрезается часть кириллических строк при создании vCard QR-кода с помощью qrlib.php?

    @ksnk
    Проблема в версии vCard. Должна быть
    VERSION:3.0 , чтобы проблем с utf было меньше
    Ответ написан
  • Как мне убрать все эмодзи?

    @ksnk
    .../iu' ...

    просто добавь ключик U
    Ответ написан
    Комментировать
  • Как удалить все телефоны из текста?

    @ksnk
    А Fax с номером, это, типа, не телефон ?
    Телефон - это последовательность из не менее чем 9 цифр (пока-пока 5-6 значные телефончики городков России)
    Между цифрами (и перед ними) могут быть () пробел и тире
    $re = '/((?:[-\s\(\)]*\d){9,})/m';
    $str = 'D-24986 Satrup Tel. (0 46 33) 9 645 00 Fax (0 46 33) 9 66 000
    Problemen: Tel. 03682-4654000,';
    
    preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
    
    // Print the entire match result
    var_dump($matches);
    Ответ написан
    Комментировать
  • Как сделать так, чтобы не создавалось много файлов php после обновления страницы,а только один файл переменной $to после регистрации?

    @ksnk
    Много файлов - это про первые 3 строчки скрипта ? А накой они вообще создаются ? Выкинуть не пробовал ?
    Ответ написан
    Комментировать
  • Как в php запустить математические операции из строки?

    @ksnk
    Вот - без евалов и смс... Хотя неплохо бы проверить корректность получающегося кода. В 7 php есть контроль ошибок синтаксиса. Прикручивается факультативно.. Еще неплохо бы контролировать что выполняется и откуда оно берется.
    $vars=[
        'var1'=>100,
        'var3'=>2
    ];
    
    echo execute('{var1}/{var3}', $vars);
    
    
    function execute($expr,$vars){
    
        $functionname='_'.md5($expr);
        if(!function_exists($functionname)){
            $filename=$functionname.'.tmp.php';
            if(!file_exists($filename)) {
                $php_expr = preg_replace_callback('/{(.*?)}/', function ($m) use ($vars) {
                    if (isset($vars[$m[1]]))
                        return '$' . $m[1];
                    else
                        return $m[0];
                }, $expr);
    
                file_put_contents($functionname . '.tmp.php', sprintf('<' . '?php
            function %s($vars){
                extract($vars);
                return %s;
            }
    ', $functionname, $php_expr));
            }
            include_once($functionname.'.tmp.php');
        }
        return $functionname($vars);
    
    }
    Ответ написан
    2 комментария
  • Где ошибка preg_replace (): Неизвестный модификатор 'g'?

    @ksnk
    Не надо ничего предпочитать. Нужно использовать правильный мед...
    preg_replace("/href=\"".preg_quote($url,'/')."\"/i", "href=\"$base/$url\"", $html);
    Ответ написан
    2 комментария
  • Как передать некоторые данные в SQL запрос используя AJAX?

    @ksnk
    Просто тупо выведи на экран что у тебя приходит в массиве POST и постарайся понять что случилось.
    В приходящих данных НЕТ поля с именем data
    Ответ написан
    Комментировать