Показаны сообщения с ярлыком php. Показать все сообщения
Показаны сообщения с ярлыком php. Показать все сообщения

воскресенье, 13 марта 2016 г.

Как настроить mbstring.func_overload=0 для отдельного сайта?

Сегодня мы рассмотрим одну распространенную проблему, с которой зачастую сталкиваются многие web-программисты, системные администраторы и т.п., имеющие shared-хостинг и несколько проектов, часть из которых построена на CMS Битрикс, часть на других. Как известно, для корректной работоспособности CMS Битрикс в php.ini должны быть указаны соответствующие значения mbstring.internal_encoding и mbstring.func_overload. Допустим что нужные значения в php.ini у вас уже выставлены должным образом:

mbstring.internal_encoding = UTF-8
mbstring.func_overload = 2

И ваш Битрикс проект отлично работает. Теперь, вы хотите создать на том же хостинге отдельный виртуальный хост и установить туда другую CMS. Как правило, в случае если у вас shared хостинг вы не можете редактировать настройки Apache и nginx с помощью конфигов, а возможности панели управления для редактирования параметров виртуальных хостов достаточно скудные.  В результате системная настройка mbstring.func_overload = 2 в php.ini действует на все ваши сайты, размещенные на этом хостинге. Но что хорошо для Битрикса - плохо для других CMS, т.е. CMS установленная на том же хостинге, но на другом сайте mbstring.func_overload = 2 вовсе не нужен, там должно быть значение 0. Как же исправить эту ситуацию? Для начала несколько полезных ссылок:

Из которых мы узнаем что в ранних версиях PHP все было достаточно просто, т.е. управлять параметром mbstring.func_overload можно было из .htaccess. Т.е. достаточно было указать в .htaccess что-то вроде:

<IfModule mod_php5.c>

  #php_value mbstring.func_overload 2 
  #php_value mbstring.internal_encoding utf-8 

  php_value mbstring.func_overload 0 
  php_value mbstring.internal_encoding cp1251 

</IfModule>
При этом значения переопределялись. Однако, начиная с версии PHP 5.3 менять в .htaccess mbstring.func_overload действительно нельзя. Ни с помощью php_admin_value, ни с помощью php_value они не меняются. Для примера на моем PHP 5.4.34 именно так и было, данные настройки ни в .htaccess ни в .user.ini (есть и такой) не подхватывались. Воспользоваться же советом по редактированию конфигов Apache, чтобы сделать так:

<Directory /var/www/path/to/dir>
php_admin_value mbstring.func_overload 0
</Directory>
В моем случае тоже не получалось, т.к. доступ к их редактированию на shared-хостинге тоже отсутствует. Но выход есть. Ведь параметры для каждого конкретного хоста можно задавать в соответствующих разделах php.ini, которые появились как раз, начиная с 5.3.

Т.е. для решения поставленной задачи нам достаточно было прописать в php.ini следующие строки:

[HOST=www.site2.ru]
mbstring.func_overload=0

При этом Master Value для mbstring.func_overload так и останется равным 2, а вот Local Value для указанного нами хоста будет 0:


Бинго, проблема решена.

пятница, 3 октября 2014 г.

Битрикс. Сортировка элементов инфоблока в $arResult.

И снова мы возвращаемся к Битриксу ;) Чувствую про него будет еще десяток постов. Во время работы над проектом всегда возникают какие-то вопросы, требующие либо нетривиального подхода, либо поиска информации. Естественно, все они решаются, и вот методом их решения, как раз и хочется "поделиться с потомками". Мало ли кому будет полезным. Итак представьте, что у нас есть некий массив $arResult['ELEMENTS'] полученный из элементов инфоблока. Чтобы пример не был таким абстрактным, в качестве примера возьмем компонент bitrix:iblock.element.add.list, который выводит список Список своих элементов с привязкой к пользователю. Т.е. к примеру, если у вас "Доска объявлений", то у пользователя в личном кабинете должен быть доступен список объявлений которые он подавал. Но вот беда ... компонент выводит элементы пользователя в $arResult['ELEMENTS'], который с помощью свойств компонента никак нельзя ни отсортировать, ни изменить и т.п. Что несколько неудобно. Например, нам нужно вывести все объявления пользователя, начиная с последнего ...

На помощь нам придет result_modifier.php и Класс для сортировки массива, usort [php]. Исходный код класса:

class CCabinet_SortObject {

 function __cmp_ValueOf($a, $b, $name, $order) {
  if(is_set($a[$name]) && is_set($b[$name])) {
   if($order == 'ASC')
    return ($a[$name]<$b[$name])?true:false; 
   elseif($order == 'DESC')return ($b[$name]>$a[$name])?false:true;
  }
 }

 function cmp_STATUS_ASC($a, $b) {
  return CCabinet_SortObject::__cmp_ValueOf($a, $b, "STATUS", "ASC");
 }

 function cmp_STATUS_DESC($a, $b) {
  return CCabinet_SortObject::__cmp_ValueOf($a, $b, "STATUS", "DESC");
 }

 function cmp_NAME_ASC($a, $b) {
  return CCabinet_SortObject::__cmp_ValueOf($a, $b, "OBJECT_NAME", "ASC");
 }

 function cmp_NAME_DESC($a, $b) {
  return CCabinet_SortObject::__cmp_ValueOf($a, $b, "OBJECT_NAME", "DESC");
 }

 function cmp_CITY_ASC($a, $b) {
  return CCabinet_SortObject::__cmp_ValueOf($a, $b, "CITY_NAME", "ASC");
 }

 function cmp_CITY_DESC($a, $b) {
  return CCabinet_SortObject::__cmp_ValueOf($a, $b, "CITY_NAME", "DESC");
 }

 function cmp_DATE_DESC($a, $b) {
  if ($a["DATE_CREATE"] == $b["DATE_CREATE"]) {
         return 0;
     }
     return ($a["DATE_CREATE"] > $b["DATE_CREATE"]) ? -1 : 1;
 }

 function cmp_DATE_ASC($a, $b) {
  if ($a["DATE_CREATE"] == $b["DATE_CREATE"]) {
         return 0;
     }
     return ($a["DATE_CREATE"] < $b["DATE_CREATE"]) ? -1 : 1;
 }

}

Автор приводит такой пример вызова:

usort($arResult['ITEAM'], array("CCabinet_SortObject", "cmp_".$arParams['SORT_BY']."_".$arParams['SORT_ORDER']));

Но нам нужно отсортировать объяления по дате создания. Поэтому внутри result_modifier.php мы поступаем следующим образом:

usort($arResult['ELEMENTS'], array("CCabinet_SortObject", "cmp_"."DATE"."_"."DESC"));

В результате объявления отсортированы у нас по дате. Профит. Хочется сказать спасибо автору блога yunaliev.ru за сэкономленное время и универсальный метод.