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

    gromdron
    @gromdron
    Работаю с Bitrix24
    На эту тему есть замечательная статья: ashep.org/2013/using-spl-iterators-1

    Коротко пару выжимок:
    Цикл foreach создаёт копию полученного массива. Если вы имеете дело с большими объёмами данных, такой подход не годится по очевидной причине: снижение производительности. Итератор SPL работает по другому: он обрабатывает один элемент итерируемого списка за раз, делая это куда более эффективно, нежели foreach.


    При создании поставщиков данных (data providers) итераторы помогают сделать их более эффективными, предлагаю возможности ленивой загрузки (lazy loading). «Ленивая загрузка» означает то, что фактическое получение данных из источника выполняет только тогда, когда эти данные нужны. Помимо прочего, вы получаете возможность трансформации данных перед тем, как отдавать их клиенту объекта.
    Ответ написан
    Комментировать
  • Не знаю в чем проблема внесения данных на сервер, вопрос по идее вообще легкий, но я не знаю в чем ошибка, поможете?

    gromdron
    @gromdron
    Работаю с Bitrix24
    1) Если id - primary и autoincrement, то заполнять его не нужно.
    То есть нужно делать так:

    $query = mysqli_query($con, "INSERT INTO sales (name, color, adress, tel) VALUES (`{$name}`, `{$color}`, `{$adress}`, `{$tel}`)");


    2) Нужно же понять что именно пошло не так - поэтому

    if ( !$query )
    {
    	var_dump(mysqli_error($con));	
    }
    Ответ написан
    6 комментариев
  • Чат-бот для Битрикс24. Как скачать вложения сообщений (фото, аудио и т.п.)?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Ну... попробуйте запросить для Бота права на Диск и при помощи метода dev.1c-bitrix.ru/rest_help/disk/file/disk_file_get.php
    Скачать его.

    По факту: в [urlDownload][default] в ссылке fileId это ID файла на диске и его можно получить.

    Но это скорее хак, чем оф. возможность.
    Ответ написан
  • Могут ли print_r, echo и var_dump "убить" скрипт?

    gromdron
    @gromdron
    Работаю с Bitrix24
    В публичной части битрикса: Да, могут, но оочень большой переменной (например объекта с вложенными объектами)

    Если внимательно читать документацию по Битриксу, а именно: https://dev.1c-bitrix.ru/api_help/main/general/pag...
    Можно заметить, что вывод не направляется сразу в браузер, а с шага 1.14 до 5.2 происходит буферизация вывода.
    Соответственно при достижении определенного лимита - скрипт упадет.
    Ответ написан
    4 комментария
  • Почему не работает отправка письма с сайта?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Вангую что переехали на nginx+php-fpm?
    Посмотрите советы: Как убрать No input file specified?
    Ответ написан
    Комментировать
  • Получение номер столбца в Excel с помощью библиотеки phpspreadsheet?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Есть почти то, что Вы хотите, но без указания номера строки. т.е. если отделить строку от столбца, то получается нижеследующее:
    use \PhpOffice\PhpSpreadsheet\Cell\Coordinate;
    
    // Выведет: Z
    var_dump(Coordinate::stringFromColumnIndex(26));
    
    // Выведет: R
    var_dump(Coordinate::stringFromColumnIndex(18));
    
    // Выведет 2
    var_dump(Coordinate::columnIndexFromString('B'));
    
    // Выведет 26
    var_dump(Coordinate::columnIndexFromString('Z'));

    См. https://phpspreadsheet.readthedocs.io/en/develop/t...
    Ответ написан
    Комментировать
  • Как сделать правильно выборку?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Попробуйте так:
    $sql = "SELECT
      `login`,
      `prava`,
      CASE
        WHEN prava=1 THEN 'Модератор'
        WHEN prava=3 THEN 'Ст. Модератор'
        ELSE 'Не определены'
      END user_role
    FROM accounts
    WHERE prava >= 1";
    
    $prava = R::getAll($sql);
    Ответ написан
  • Как заставить битрикс не кешировать определенные участки кода в шаблоне?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Простите конечно, но дичь в данном случае то, что предлагаете Вы. Ни один фрейморк не поддерживает "не кеширование определенной области внутри кешируемой" (найдете опровержение - с удовольствием побеседуем и рассмотрим как возможно применение данного алгоритма).

    Собственно в Битриксе есть 2 механизма для решения Вашего кейса:

    1) Убрать кеширование результата (html) и сделать кеширование данных.
    На мой взгляд не лучший вариант, так как на рендеринг тоже нужны ресурсы, которые и так дорогие

    2) Определить дополнительный ключ кеширования.
    В StartResulCache во 2 параметр можно добавить свои ключи, и в данном случае у Вас это будет ключ устройства пользователя (mobile / desktop), после чего будет хранится 2 кеша: для мобильных и для десктопных клиентов.
    Ответ написан
    4 комментария
  • Как можно посчитать часы и минуты по тарифу?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Посмотрите как работает в date G и i, как php читает запятую при приведении типов.

    Немного дополненный пример.

    /* @var float Стоимость минуты разговора, в данном случае 55 рублей 56 копеек */
    $rateMinutes = 55.56;
    
    /* @var DateTime Время начало разговора/события */
    $oStartDate = new \DateTime('11.10.2017 10:37:00');
    
    /* @var DateTime Время оконачания разговора/события */
    $oEndDate = new \DateTime('11.10.2017 10:47:00');
    
    /* @var int Длительность события в секундах */
    $durationSeconds = abs($oEndDate->getTimestamp()-$oStartDate->getTimestamp());
    
    /* @var int Длительность события в минутах, округленных в большую сторону */
    $durationMinutes = round($durationSeconds/60);
    
    /* @var float Стоимость разговора/события */
    $price = $durationMinutes * $rateMinutes;
    
    // Выводим стомость разговора/события
    var_dump($price);
    Ответ написан
    Комментировать
  • Кто нибудь может накидать вариантов почему такие разрывы в коде?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Окей, почему такие большие разрывы в коде?

    1) Возможно ошибка в самом файле шаблона. Нужно проверить все шаблоны на предмет символов в цикле.
    Можно попробовать заменить свой шаблон меню, стандартным шаблоном битрикса. Помогло? Ошибка в шаблоне. Нет? Ошибка в другом месте.

    2) Возможно ошибка кроется в result_modifier.php шаблона.
    Файла нет или ошибки в нем нет? Ошибка в другом месте.

    3) Возможно кто-то вынес меню в local или изменил файл в ядре (/bitrix/components/bitrix/menu).
    Ядро не менялось и компонента в local нет? Ошибка в другом месте.

    4) Возможно используется расширенное меню и ошибка в нем.
    Если расширенное меню не используется или в нем нет ошибки, то ошибка в другом месте

    5) Возможно ошибка при формировании меню.
    Например пункты меню формируются php кодом или внутри происходит какой-то include/require

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

    gromdron
    @gromdron
    Работаю с Bitrix24
    Коллеги, мне кажется Вы забываете об уровнях изоляции.
    PHP ini подгружается не в самом php, а в apache, соответственно при обработке .htaccess он имеет бОльший приоритет.
    Соответственно в ini_get Вы получите те значения, которые действуют в момент вызова ini_get в рамках данного хита.

    Примечание: не все значения можно переопределить в .htaccess (например mbstring.func_overload)
    Ответ написан
    Комментировать
  • Как изменить значение php_value mbstring.func_overload для определенного сайта на локальном сервере?

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

    1) Открываем меню в трее: Дополнительно -> Конфигурация -> Apache 2.* (у меня 2.4) (выбираем пункт)
    2) У вас откроется редактор с примерно таким кодом:
    #-----------------------------------------------#
    # Начало блока конфигурации HTTP хоста
    #-----------------------------------------------#
    
    <VirtualHost *:%httpport%>
    
        DocumentRoot    "%hostdir%"
        ServerName      "%host%"
        ServerAlias     "%host%" %aliases%
        ScriptAlias     /cgi-bin/ "%hostdir%/cgi-bin/"
    
    </VirtualHost>

    У меня OpenServer находится на диске E, соответственно путь до папки с битриксом получается такой: E:/OpenServer/OpenServer/domains/dev

    Вписываем волшебный кусочек кода:
    <Directory "E:/OpenServer/OpenServer/domains/dev">
    	AllowOverride All
    	php_admin_value mbstring.func_overload 0
    </Directory>

    Чтобы получилось на подобии этого:
    #-----------------------------------------------#
    # Начало блока конфигурации HTTP хоста
    #-----------------------------------------------#
    
    <VirtualHost *:%httpport%>
    
        DocumentRoot    "%hostdir%"
        ServerName      "%host%"
        ServerAlias     "%host%" %aliases%
        ScriptAlias     /cgi-bin/ "%hostdir%/cgi-bin/"
    	
    	<Directory "e:\openserver\openserver\domains\cli">
    		AllowOverride All
    		php_admin_value mbstring.func_overload 0
    	</Directory>
    	
    	<Directory "E:/OpenServer/OpenServer/domains/dev">
    		AllowOverride All
    		php_admin_value mbstring.func_overload 0
    	</Directory>
    
    </VirtualHost>

    Сохраняем файл

    3) Перезагружаем OpenServer (желтый флажок)

    Примечание: метод работает только в web окружении, в консоли вы будете по-прежнему со значениями из Вашего php.ini файла
    Ответ написан
    5 комментариев
  • Какой компонент Битрикс подойдет для отправки заявки в личном кабинете?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Здесь дело не в компоненте, а в способе реализации, которая в свою очередь зависит от редакции.
    Например для Битрикс24 их много. Навскидку варианты следующие:
    1) Универсальный список с бизнес-процессом на нем
    2) Элемент инфоблока с бизнес-процессом на нем (есть и в БУС)
    3) Веб-формы и этапы прохождения (есть и в БУС)
    4) Собственная реализация на инфоблоках
    5) Релаизация на основе собственного кода

    Например если взять вариант 1, то там вообще делать ничего не нужно. Только права правильно настроить и бизнес-процесс описать.
    А вот, например в форме 4 - bitrix:iblock.element.add и собственный код согласования.
    Ответ написан
    Комментировать
  • Как сгруппировать элементы по разделам в Битрикс?

    gromdron
    @gromdron
    Работаю с Bitrix24
    А не пробовали воспользоваться штатной возможностью группировки: arGroupBy (3 параметр в getList, который у вас в значении false)

    Массив полей для группировки элемента. Если поля указаны, то выборка по ним группируется (при этом параметр arSelectFields будет проигнорирован), а в результат добавляется поле CNT - количество сгруппированных элементов. Если указать в качестве arGroupBy пустой массив, то метод вернет количество элементов CNT по фильтру. Группировать можно по полям элемента, а также по значениям его свойств. Для этого в качестве одного из полей группировки необходимо указать PROPERTY_, где PROPERTY_CODE - ID или символьный код свойства.
    Необязательное. По умолчанию false - записи не группируются.


    Группировать по ID секции.
    Ответ написан
    Комментировать
  • PHP 7 Как переделать из preg_replace в preg_replace_callback?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Честно говоря, без говнокода не представляю как сделать подобное.
    Если уж очень топорный вариант. Первое что приходит в голову - либо класс передавать, либо глобал использовать. Глобальные переменные это как-то уж очень через чур, а вот с классом другое дело (выглядит почище, да и для глаз приятнее).

    Навскидку, код, который будет отвечать за вывод будет следующим:
    /* @var string Текст, в котором проводим замену*/
    $str = <<<STRTEXT
    [index:Звездочет]А тут хз что[/index]
    Тут текст [guest]Иванов[/guest]
    STRTEXT;
    
    $oTextParser= (new TextParser($str))
    				->addRule("#\\[index:(.+?)\\](.*?)\\[/index\\]#ies", "indexShow('\\1', '\\2')")
    				->addRule("#\\[guest](.*?)\\[/guest]#ies","checkGuest('\\1')")
    				->parse();
    
    /*
    На выходе хочу получить:
    -------------------------
    Звездочет(А тут хз что)
    Тут текст GUEST(Иванов)
    */
    
    echo "<pre>";
    var_dump($oTextParser->getText());
    echo "</pre>";

    Код функций который я буду использовать:
    function indexShow( $a, $b)
    {
    	return $a."(".$b.")";
    }
    
    function checkGuest( $a )
    {
    	return 'GUEST('.$a.')';	
    }


    Сама реализация:
    class TextParser
    {
    	/* @var string Результат выполнения парсинга */
    	public $parsed;
    
    	/* @var string[] Ассоциативный список правил в формате: регулярка => функция для замены */
    	public $rules = [];
    
    	public function __construct( $text )
    	{
    		$this->parsed = $text;
    	}
    
    	/**
    	 * Добавляет правило работы парсера
    	 * Для использования цепочек возвращает текущий экземпляр
    	 * 
    	 * @param string $regex 
    	 * @param string|callback $func 
    	 * @return TextParser
    	 */
    	public function addRule( $regex, $func )
    	{
    		$this->rules[ $regex ] = $func;
    		return $this;
    	}
    
    	/**
    	 * Выполняет разброр исходного текста
    	 * Для использования цепочек возвращает текущий экземпляр
    	 * 
    	 * @return TextParser
    	 */
    	public function parse()
    	{
    		array_walk(
    			$this->rules,
    			function($function, $regular)
    			{
    				$this->parsed = preg_replace($regular, $function, $this->parsed);
    			}
    		);
    		return $this;
    	}
    
    	/**
    	 * Возвращает результат парсера (или исходный текст, если был вызван до метода parse)
    	 * 
    	 * @return string
    	 */
    	public function getText()
    	{
    		return $this->parsed;
    	}
    
    }


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

    gromdron
    @gromdron
    Работаю с Bitrix24
    Мой коллега, сейчас участвует в программе менторства по Базовому курсу php от HTLM Academia. Не могу говорить за всех, но в качестве данного курса я уверен:
    1) Должная подготовка - php, composer, github , mysql - знания которые вы получите на выходе, плюс понимание как это работает
    2) Работа с ментором позволит устранить узкие места в Вашем коде и если нужно поставит логику на место.

    По специалисту ничего не могу сказать, но из GeekBrains так себе специалисты (был опыт).

    Вообще в мире и у нас сильно котируется только ZCE, а чтобы его сдать не обязательно где-то учиться, можно и на документации.
    Но вообще, рекомендую курсы от html академии + сдача ZCE. На выходе - вы сертифицированный специалист по php с хорошим портфолио на GitHub
    Ответ написан
  • Как создать кастомное действие с привязкой к элементу?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Впринципе не сложно.

    Для начала Вы подписываетесь на событие OnAdminListDisplay модуля Main.
    Именно оно отвечает за действие ДО вывода любого списка элементов в административной панели (за исключением под-листов у инфоблоков и модуля производительности).
    На вход оно принимает лишь 1 параметр - экзепляр класса CAdminList (см. /bitrix/modules/main/interface/admin_list.php)

    Чтобы обрабатывать нужную таблицу, нужно ограничить выборку. Т.е. Ваш обработчик будет выглядеть как-то так:

    <?php
    AddEventHandler("main", "OnAdminListDisplay", "MyOnAdminContextMenuShow");
    function MyOnAdminContextMenuShow(&$oAdminList)
    {
        /**
         * $type - тип кода инфоблока, например news, events и т.д.
         * $iblock - идентификатор инфоблока
         * 
         * Если интересует каталог, то вместо tbl_iblock_list_ нужно использовать tbl_product_list_
         */
        if ( $oAdminList->table_id == "tbl_iblock_list_".md5($type.".".$iblock) )
        {
            // полезные действия
        }
    }
    ?>


    Собственно так, мы получаем возможность работать с выводом.
    Для более подробного пояснения лучше прочитать про заказные элементы в административной панели в документации: https://dev.1c-bitrix.ru/api_help/main/general/adm...

    Собственно добавим нужные нам данные для работы. Предположим, я хочу логгировать выделенные элементы на странице, тогда мой код будет выглядеть так:
    AddEventHandler("main", "OnAdminListDisplay", "MyOnAdminContextMenuShow");
    function MyOnAdminContextMenuShow(&$oAdminList)
    {
        /**
         * $type - тип кода инфоблока, например news, events и т.д.
         * $iblock - идентификатор инфоблока
         * 
         * Если интересует каталог, то вместо tbl_iblock_list_ нужно использовать tbl_product_list_
         */
        if ( $oAdminList->table_id == "tbl_iblock_list_".md5("structure.4") )
        {
        	$arActions = $oAdminList->arActions;
    
        	$arActions['alert'] = 'Ругаться!';
    
        	$oAdminList->AddGroupActionTable($arActions);
        }
    }
    
    AddEventHandler("main", "OnAfterEpilog", "iblockAlert");
    
    function iblockAlert()
    {
    	$oRequest = \Bitrix\Main\Application::getInstance()->getContext()->getRequest();
    
    	// Проверяем, что работает только в админке
    	if ( $oRequest->isAdminSection() )
    	{
    		if (
    			// Интересуют только интерактивные запросы
    			$oRequest->get('mode')=='frame'
    			// Где передана переменна IBLOCK_ID
    			&& $oRequest->get('IBLOCK_ID')==4
    			// Соответствующие нашему action
    			&& $oRequest->get('action')=='alert'
    			)
    		{
    			/**
    			 * Вот тут можно сделать что угодно
    			 * Можно получить выделенные ID
    			 * через $oRequest->get('ID')
    			 * Если он пуст, значит действие на всех элементах инфоблока
    			 */
    		}
    	}
    }


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

    gromdron
    @gromdron
    Работаю с Bitrix24
    В меня конечно сейчас попытаются запустить камнем, но - 1С-Битрикс имеет штатную интеграцию + модули для о...

    Правда выйдет недешево и если 1С-ка пиленая придется попотеть, но в целом документация по обмену хорошая.
    Ответ написан
    Комментировать
  • Как надежно выполнить несколько запросов mysql (mysqli)?

    gromdron
    @gromdron
    Работаю с Bitrix24
    Ответ - нет. Функция mysqli_multi_query выполнит все запросы так, как если бы Вы использовали обычное query.
    К тому же, она вернет FALSE, только если ПЕРВОЕ выражение вызвало ошибку.

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

    gromdron
    @gromdron
    Работаю с Bitrix24
    Для начала, ознакомьтесь с имеющийся документацией: https://dev.1c-bitrix.ru/learning/course/?COURSE_I...
    Внизу странице (по ссылке выше) есть код агента, исполняющегося под cron. Он подойдет.

    Первое на что нужно обратить внимание: константа SITE_ID. Если предполагается работа из админ панели, то это константа языка, иначе - константа сайта (лучше задать вручную)
    Второе: проверьте $_SERVER["DOCUMENT_ROOT"] (если у Вас bitrix vm то это скорее всего тот же путь)
    И третье - вместо echo в cli режиме лучше использовать: fwrite( STDOUT, 'Строка' );
    Ответ написан
    Комментировать