Задать вопрос
Ответы пользователя по тегу PHP
  • Использовать ли регулярные выражение?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Иными словами: у Вас есть некоторая строка длинной X и Вы хотите оставить в ней только символы по маске а-яА-Яa-zA-Z0-9 (прописные и строчные буквы русского и латинского алфавита + цифры + пробел). Если тотально не доверяете пользователю, я бы рекомендовал все же использовать регулярное выражение, так как в unicode более 8 тысяч символов и ни один из существующих php-функций не вернет Вам их все. В таком случае, регулярное выражение обеспечит наиболее удобный, легкочитаемый и быстрый вариант.

    Но есть одно НО - длинна строки (pcre.recursion_limit). Например при строке в 4096 символов Вы в легкую можете получить Segmentation fault и работа скрипта прекратится.
    Ответ написан
    Комментировать
  • Что я в итоге реализовал?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Эм... есть несколько вопросов по Вашему "чуду".
    Отбросив велосипедизм и костылестроение есть пара вопросов по логике работы.

    То что у Вас есть константа MAX_AGE_IN_YEARS (кстати почемы бы просто не спрашивать дату рождения?) это ок (смущает конечно _IN_YEARS, но да ладно), то что у Вас 3 пола это тоже допустимо (по крайней мере в нашей адекватной России), то что у Вас есть допустимый ростовой диапазон тоже, но во чего я точно не могу понять, так это блин STATUSES.

    Почему бы не сделать 2 "статуса" (на самом деле эт о скорее "признак жизни субьекта") - DEAD или ALIVE, то есть живой или не живой.
    child, adult, old и т.п. можно получить при помощи отдельного метода исходя из возраста обьекта (ведь они же зависят от возраста, а не от каких либо правил).
    "Статусы" buried и cremated это не статусы, а виды погребения.

    Велосипедизм вызван именно нежеланием разделять физические сущности на их логические составляющие.

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

    gromdron
    @gromdron
    Работаю с Bitrix24
    Проверьте директиву allow_url_fopen в php.ini.
    Ответ написан
    Комментировать
  • Что за ошибка mysqil?

    gromdron
    @gromdron
    Работаю с Bitrix24
    "(NULL, '$cart_id_product', '123', '44', '$cart_ip'


    А скобку кто закроет?
    Ответ написан
  • Как сделать кнопку отправки вложения?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Загрузка файлов
    Для отправки почты использовать что-нибудь попроще: PHPMailer или Swift Mailer

    Неплохо было бы почитать по Чистый код на php и PHP: The Right Way
    Ответ написан
  • Какой способ получения IP лучше?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Ну хз, на мой взгляд это не равноценные примеры: субьективно читать первый не проще, я бы отдал предпочтение функции get_ip(), с другой стороны второй пример не делает того же, что делает первый (например валидацию не проводит).

    /**
     * Return client ip if find, or null
     * @return string|null
     */
    function getUserIp()
    {
        static $ip;
    
        if ( !is_null($ip) )
        {
            return $ip;
        }
    
        $candidates = [
            @$_SERVER['HTTP_CLIENT_IP'],
            @$_SERVER['HTTP_X_FORWARDED_FOR'],
            @$_SERVER['REMOTE_ADDR']
        ];
    
        foreach ($candidates as $candidate)
        {
            if ( \filter_var($candidate, \FILTER_VALIDATE_IP) )
            {
                $ip = $candidate;
                break;
            }
        }
    
        return $ip;
    }
    
    var_dump(getUserIp());
    Ответ написан
    Комментировать
  • Как из двух массивов сделать один двумерный массив?

    gromdron
    @gromdron
    Работаю с Bitrix24
    В Вашем случае есть 2 ограничения:
    1) Если у Вас будет 2 пользователя с одинаковым именем, то их данные смешаются в одну кучу
    2) Если немного изменить формат $users то будет значительно проще получить результирующий массив (не нужен будет первый цикл на ассоциативность)

    /**
     * Шаг 1 - разворачиваем $users в плоский массив
     * Если есть возможность получить его сразу ассоциативным,
     * то это было бы лучше
     */
    $usersAssoc = [];
    
    foreach ($users as $user)
    {
    	$usersAssoc[ $user['id'] ] = $user['name'];
    }
    
    /**
     * Шаг 2 - выполяем группирующее преобразование наших $punch
     */
    $result = [];
    
    foreach ($punch as $time)
    {
    	if ( !array_key_exists($time['user_id'], $usersAssoc) )
    	{
    		// В punch есть массив, который относится к пользователю
    		// о окотором мы не знаем
    		continue;
    	}
    
    	$result[ $usersAssoc[ $time['user_id'] ] ][ $time['id'] ] = $time;
    }
    
    
    echo "<pre>";
    var_dump($result);
    echo "</pre>";
    Ответ написан
  • Кто-то видел Blueprint Interface для php?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Эм.. а какой кейс это закроет?
    А UE насколько я знаю, это заменяет все - и подход стандартизирован и действия и взаимоотношения.
    В вебе нет такой проблемы - классы обычно запиливаются для конкретного ORM/DataMapper и где-то, даже есть свой скаффолдинг.
    Ответ написан
  • Как выполнить поиск в JSON?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Если Вы не хотите работать с json, то почему вы не пробовали работать с ним как с строкой?
    Ответ написан
    Комментировать
  • Как закодировать строку в Unicode последовательность?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Если Вы уверены что на входе будут только a-zA-Z0-9-=+- (похоже на base64) то можно упростить и не перекодировать, например так:

    $uncomingString = 'W+I4zLZyeJDAhQMe33tYRcXC+Falj9baMfjJw5yOijaPNHDYcnNlRlTGm3rvA6cn2hXMmW4ZKEyTphwzNMQlOlnNiCHK2LLpJLgXK6JHKuTYeParwqCud5Vn2dZXpxctrQf8OkbCqF12u0GcBR2or2HFBrEV13Jd5YAX4bRbUBk=';
    
    
    function forceUnicode( $str = '' )
    {
    	$result = '';
    
    	for( $i=0,$length=strlen($str); $i<$length; $i++)
    	{
    		$result .= "\\u".str_pad(bin2hex($str[$i]), 4, '0', STR_PAD_LEFT);
    	}
    
    	return $result;
    }
    
    echo forceUnicode($uncomingString);
    
    /*
    Выведет: 
    \u0057\u002b\u0049\u0034\u007a\u004c\u005a\u0079\u0065\u004a\u0044\u0041\u0068\u0051\u004d\u0065\u0033\u0033\u0074\u0059\u0052\u0063\u0058\u0043\u002b\u0046\u0061\u006c\u006a\u0039\u0062\u0061\u004d\u0066\u006a\u004a\u0077\u0035\u0079\u004f\u0069\u006a\u0061\u0050\u004e\u0048\u0044\u0059\u0063\u006e\u004e\u006c\u0052\u006c\u0054\u0047\u006d\u0033\u0072\u0076\u0041\u0036\u0063\u006e\u0032\u0068\u0058\u004d\u006d\u0057\u0034\u005a\u004b\u0045\u0079\u0054\u0070\u0068\u0077\u007a\u004e\u004d\u0051\u006c\u004f\u006c\u006e\u004e\u0069\u0043\u0048\u004b\u0032\u004c\u004c\u0070\u004a\u004c\u0067\u0058\u004b\u0036\u004a\u0048\u004b\u0075\u0054\u0059\u0065\u0050\u0061\u0072\u0077\u0071\u0043\u0075\u0064\u0035\u0056\u006e\u0032\u0064\u005a\u0058\u0070\u0078\u0063\u0074\u0072\u0051\u0066\u0038\u004f\u006b\u0062\u0043\u0071\u0046\u0031\u0032\u0075\u0030\u0047\u0063\u0042\u0052\u0032\u006f\u0072\u0032\u0048\u0046\u0042\u0072\u0045\u0056\u0031\u0033\u004a\u0064\u0035\u0059\u0041\u0058\u0034\u0062\u0052\u0062\u0055\u0042\u006b\u003d
    */


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

    gromdron
    @gromdron
    Работаю с Bitrix24
    Замените
    if (isset($brand)){
    На
    if ( !empty($brand) ) {
    И еще:
    $query = "SELECT * FROM products WHERE brand =  '".$_POST["category"]."' ";

    Почитайте про SQL Injection
    Ответ написан
    Комментировать
  • Почему не удается получить ответ от сервера soap wsdl php Curl?

    gromdron
    @gromdron
    Работаю с Bitrix24
    А зачем Вы вручную это делаете?
    Начнем с того, что в php есть расширение php-soap, которому только скормить адрес wsdl и вызывать уже готовые методы.

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

    gromdron
    @gromdron
    Работаю с Bitrix24
    А что Вы хотите? Вы же его явно затираете в строке:
    $data[$row['question_id']] = $row['answer_id'] ;
    Запихивайте массив:
    $data[$row['question_id']][] = $row['answer_id'] ;

    При складывании 1к1 (1 вопрос = 1 ответ) - Ваша структура подойдет, а при 1 вопрос => много ответов уже нет.
    Ответ написан
    Комментировать
  • $_POST принимает NULL при AJAX запросе и мешает использовать PDO, как исправить?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Если Вы НЕ отметили ни одного чек-бокса, то Вам ничего и не прилетит.
    Т.е. если отправить форму из моего примера, в $_POST будет:
    array(2) {
      ["a"]=>
      string(1) "0"
      ["b"]=>
      string(1) "5"
    }

    Т.е. никакого day у Вас и нет.
    Я так понимаю, Вы делаете вывод данных на основе значения этого day. А значит ничего не и должно вывестись.

    То есть, Ваш код сведется к:
    $result = [];
    
    $a = (int) $_POST['a'];
    $b = (int) $_POST['b'];
    
    $c = array_filter( (array) $_POST['day'] );
    
    if ( !empty($c) )
    {
    	$c = implode(',', $_POST['day']);
    	$in = str_repeat('?,', count($c) - 1) . '?';
    	$sql = "SELECT * FROM table WHERE day IN ($in) ASC LIMIT :a, :b";
    	$stmt = $pdo->prepare($sql);
    	$stmt->execute($с, [$a, $b]);
    	$data = $stmt->fetchAll();
    
    	$result = $data;
    }
    
    echo json_encode($result);


    P.S. А так ли Вам нужна именно ручная сборка значений? Почему бы не вынести в саму форму?

    <form id="filter">
    	<input type='hidden' name='a' value='0' />
    	<input type='hidden' name='b' value='5' />
    	<input type="checkbox" name="day[]" value="1"> 
    	<input type="checkbox" name="day[]" value="2">
    	<input type="checkbox" name="day[]" value="3"> 
    </form>


    $.ajax({
        url: 'index.php',
        method: 'POST',
        data: $("#filter").serialize()
    });
    Ответ написан
    1 комментарий
  • Не могу понять почему не работает var_dump?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Меняем:
    if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['edit'])) {
        $editServiceById = $services->editServiceById($_GET['service_id'], $_POST);
    }


    На:
    // Display errors 
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);
    // Log values
    echo "<pre>";
    var_dump($_SERVER['REQUEST_METHOD'], $_POST['edit'], isset($_POST['edit']));
    echo "</pre>";
    
    if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['edit'])) {
        $editServiceById = $services->editServiceById($_GET['service_id'], $_POST);
    }


    Повторяем отправку формы и смотрим что и куда не ушло. А дальше учимся дебажить банальные вещи.

    P.S. leni_m - сполерит :P
    Ответ написан
    Комментировать
  • Как объединить три массива?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Как вариант, еще один:

    /**
     * Prepare array for our job
     */
    $arrayOne = [
    	0 => 80,
    	1 => 80,
    	2 => 90,
    ];
    
    $arrayTwo = [
    	0 => [
    		0 => 190,
    		1 => 195,
    	],
    	1 => [
    		0 => 200,
    	],
    	2 => [
    		0 => 190,
    		1 => 195,
    	],
    ];
    
    $arrayThree = [
    	0 => 1,
    	1 => 2,
    	2 => 3,
    ];
    
    /**
     * @var array Array with actual data in our structure
     */
    $arResult = [];
    
    foreach ( $arrayTwo as $iKeyOne => $arrayTwoElement )
    {
    	// if in second array exist unknown key
    	if ( !array_key_exists($iKeyOne, $arrayOne) )
    	{
    		continue;
    	}
    
    	// if in third array exist unknown key
    	if ( !array_key_exists($iKeyOne, $arrayThree) )
    	{
    		continue;
    	}
    
    	// if in second array no elements
    	if ( empty($arrayTwoElement) || !is_array($arrayTwoElement) )
    	{
    		continue;
    	}
    
    	/* @var integer Key for first depth level  */
    	$iLevelKey = (int) $arrayOne[ $iKeyOne ];
    
    	/* @var integer Value for second depth level */
    	$iLevelValue = (int) $arrayThree[ $iKeyOne ];
    
    	foreach ($arrayTwoElement as $k => $v)
    	{
    		$arResult[ $iLevelKey ][ $v ] = $iLevelValue;
    	}
    }
    
    var_dump($arResult);
    /*
    Will display:
    array(2) {
      [80]=>
      array(3) {
        [190]=> int(1)
        [195]=> int(1)
        [200]=> int(2)
      }
      [90]=>
      array(2) {
        [190]=> int(3)
        [195]=> int(3)
      }
    }
    */
    Ответ написан
    Комментировать
  • Почему не работает return?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Ну так все правильно!
    Вы же получаете результат для своей строки на второй итерации, а return на первой не работает.
    Заменяем:
    encrypt($text, $m);
    На
    return encrypt($text, $m);

    И видим результат: s eT ashi tist!
    Можно конечно еще и функцию упростить:
    function encrypt($text, $n)
    {
    	if ( $n < 1 )
    	{
    		return $text;
    	}
    	$str1 = $str2 = "";
    	for($i = 0, $len = strlen($text); $i < $len; $i++)
    	{
    		if ( $i%2 == 0 )
    		{
    			$str2 .= $text[$i];
    		}
    		else
    		{
    			$str1 .= $text[$i];
    		}
    	}
    
    	return encrypt( $str1.$str2, ($n-1));
    }
      
    echo encrypt('This is a test!', 2);
    Ответ написан
    Комментировать
  • Как усовершенствовать функцию?

    gromdron
    @gromdron
    Работаю с Bitrix24
    А что Вы в ней хотите усовершенствовать?
    Ну например можно добавить typehint array у $requestTags и избавиться от проверки:

    public static function getTags(array $requestTags): array
    {
        $tags = [];
    
        foreach ($requestTags as $tag) {
            if (is_numeric($tag)) {
                $tags[] = $tag;
            } else {
                $newTag = Tag::upsert(['name' => $tag]);
                $tags[] = $newTag->id;
            }
        }
    
        return $tags;
    }


    Либо можно вынести в отдельную функицю сохранение тегов, например:

    function mapTags( array &$value )
    {
        if ( is_numeric($value) )
        {
            return $value;
        }
    
        $newTag = Tag::upsert(['name' => $tag]);
        return $newTag->id;
    }


    И тогда весь код метода свернется в:

    public static function getTags( array $requestTags ): array
    {
        return array_map('mapTags', $requestTags);
    }


    Можно просто уменьшить вложенность оставив скрипт (меньше уровней будет):

    public static function getTags($requestTags): array
    {
        $tags = [];
    
        if ( !$requestTags )
        {
            return $tags;
        }
    
        foreach ($requestTags as $tag) {
            if (is_numeric($tag)) {
                $tags[] = $tag;
            } else {
                $newTag = Tag::upsert(['name' => $tag]);
                $tags[] = $newTag->id;
            }
        }
    
        return $tags;
    }


    Если это очень частовыполняемая операция, то можно сэкономить на запросах:

    public static function getTags(array $requestTags): array
    {
        if ( empty($requestTags) )
        {
            return $requestTags;
        }
    
        $existedTags = array_filter($requestTags, 'is_numeric');
        $newTags = array_diff($requestTags, $existedTags);
    
        /**
         * Тут единый batch-метод который отправляет 
         * 1 запрос на все теги сразу.
         * В results - массив Tag, обработанных batch-методом
         */
        foreach ($results as $tag)
        {
            $existedTags[] = $tag->id;
        }
    
        return array_unique($existedTags);
    }
    Ответ написан
    1 комментарий
  • Как сделать временную ссылку на файл в PHP?

    gromdron
    @gromdron
    Работаю с Bitrix24
    В этом нет ничего сложного или необычного - все уже изобрели до Вас.
    Не виду смысла отвечать подробно ибо эту тему разобрали на хабре по косточкам от и до.

    Читать можно по ссылке: https://habrahabr.ru/post/151795/

    P.S. Скажу за себя - X-Accel-Redirect наше все :)
    Ответ написан
    Комментировать
  • Как можно оптимизировать код?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Если я все правильно понял и нигде не ошибся, то можно попробовать и так:

    <div class="currency">
      <ul>
        <? foreach ($obj as $element):?>
          <? $color = ($element['percent_change_24h'] > 0) '#4ac06a' : '#ff8d8d'; ?>
          <? $plus = ($element['percent_change_24h'] > 0) '+' : ''; ?>
          <li>
            <i class="cc <?=$element["symbol"];?> iconsi" title="<?=$element["name"];?>"></i>
            <div class="block_coin">
              <span class="coin_name"><?=$element["name"];?></span>
              <span style="color: '<?=$color;?>';" class="coin_price"><?=$element['price_usd'];?></span>
              <span style="color: '<?=$color;?>';" class="coin_change">(<?=$plus;?><?=$element["percent_change_24h"];?>%)</span>
            </div>
          </li>
        <? endforeach; ?>
      </ul>
    </div>
    Ответ написан
    2 комментария