Как закалялся код...: PHP. Строка json в cookie.

вторник, 12 августа 2014 г.

PHP. Строка json в cookie.

Я люблю json. Он позволяет удобно хранить информацию различного рода и быстро преобразовывать данные в строковое представление и обратно. API, функции или подключаемые библиотеки для работы с json есть в большинстве языков программирования что позволяет использовать данный формат повсеместно.
Однажды стояла задача сохранить utm метки для последующей передачи в CRM заказчика для последующего подсчета эффективности рекламных компаний. Конечно для более эффективного хранения и получения доступа к меткам из разных мест кода было решено использовать cookie.


Итак, в коде предполагаемой страницы входа посетителя (index.php или файл шаблона сайта) пишем:


 // Код не претендует на идеальность, просто решение возникшей задачи
 
 // Ожидаем такие параметры в строке запроса
 $expectMarks = array(
 'utm_source',
 'utm_campaign',
 'utm_medium',
 'utm_content',
 'utm_term',
 );
 
 //Складываем их в массив
 $utms = array();
 foreach($expectMarks as $utm)
 {
  if(isset($_REQUEST[$utm]))
  { 
   $utms[$utm] = $_REQUEST[$utm];
  }
 }
 
 // Ожидаем 3 обязательных параметра меток
 // utm_source, utm_campaign, utm_medium
 // К тому же данные будут перезаписываться только при переходе с рекламы
 // при наличии этих меток
 if(count($utms) > 0 
&& $utms['utm_source'] 
&& $utms['utm_campaign'] 
&& $utms['utm_medium'])
 {
  //Записываем куку
  setcookie("utm", json_encode($utms),time()+604800); // храним 7 дней (на ваше усмотрение)
 }

Значения cookie браузера при каждом запросе передаются серверу и в PHP попадают в глобальный массив $_COOKIE. Чтобы получить сохраненный параметр нужно всего лишь обратиться к массиву по ключу:


$utmArray = null;
if(!empty($_COOKIE['utm']))
{
  // Декодируем в массив если нужно для последующей обработки
  $utmArray = json_decode($_COOKIE['utm'], true);
}

Тут меня ждал сюрприз. Значение "utm" присутствовало в массиве но попытки декодировать строку функцией json_decode не увенчались успехом. Смотрим вывод значения:

  echo $_COOKIE['utm'];


{\"utm_source\":\"test\",\"utm_campaign\":\"test\",\"utm_medium\":\"cpc\",\"utm_content\":\"test\",\"utm_term\":\"testterm\"}

Все кавычки являющиеся неотъемлемой частью формата json экранированы обратным слэшем.
Вспоминаем "магические" директивы конфигурации PHP:

magic_quotes_gpc boolean

Устанавливает статус magic_quotes для GPC-операций (Get/Post/Cookie). Когда magic_quotes включены, все ' (одинарные кавычки), " (двойные кавычки), \ (обратные слэши) и NUL escape-ируются обратными слэшами автоматически. Если magic_quotes_sybase также включена, одинарные кавычки escape-ируются одинарной кавычкой вместо backslash.

Итак если директива magic_quotes_gpc=true JSON данные попадают под её условие.
Переписываем наш PHP код:


$utmArray = null;
if(!empty($_COOKIE['utm']))
{
  $utmString = $_COOKIE['utm'];
  if(get_magic_quotes_gpc() == true)
 {
// Если "магия" включена, убираем слэши
  $utmString = stripslashes($utmString);
 }
  // Декодируем в массив если нужно для последующей обработки
  $utmArray = json_decode($utmString, true);
}

Проблема решена.

P.S. Есть и другие братья нашей директивы используемые в других местах или применимые для других данных, про которые тоже не стоит забывать: magic_quotes_runtime и magic_quotes_sybase.


Комментариев нет:

Отправить комментарий