Тернарная условная операция

Тернарная условная операция или как часто любят говорить краткая запись if может принести много беды, если не понимать некоторых тонкостей.

Синтаксис следующий

 

Синтаксис:

expression ? true_value : false_value
Выполнение этой инструкции начинается с операнда expression. Если значение выражения expression истинно (true), то возвращается значение выражения true_value, иначе возвращается false_value.
Вроде все ясно.
Например, если в $id нам передается номер статьи, то используем его, если нет, то перевод на первую новость.
Как это будет выглядеть
$id = '1212';
$id = empty($id) ? $id : 1;

Однако все не так просто. Что если передадут в id буквы?

$id = 'asdas';
$id = empty($id) ? $id : 1;
//  выведет asdas

Заюзаем проверку на число

$id = is_numeric($id) ? $id : 1;

Но и тут, можно передать отрицательное число, что не есть хорошо, или 001, что может привести к проблемам в некоторых случаях, тогда запишем  так

$id = is_numeric($id)  && $id>0  ? (int)$id : 1;

 

Но мы можем развернуть эту схему в классический if else, т.е. сделать записать в одном из операндов выражение.

 

<?php

$id = 'sfg';
is_numeric($id) && $id>0  ? $id=(int)$id : $id=1;
echo $id;

Идентично

if (is_numeric($id) && $id>0){
    $id=(int)$id;
}else{
    $id=1;
}

 

 

Путаница для новичков возникает при первом просмотре примерно такого выражения, когда, вроде как переменной идет присвоение какого то выражения, а на выходе получаем совсем другое.

<?php

$id = '21';
$id = (is_numeric($id) && $id>0) && $id!=1  ? (int)$id : 1;

echo $id;

Область видимости объектов в памяти PHP

1.php Создадим объект класса и запишем его в массив.

<?php
$std = new stdClass();
$std->first = 1;
session_start();
$_SESSION['test1'] = $std;
print_r($_SESSION['test1']);

2.php В другом файле прочитаем его.

<?php
session_start();
$std = $_SESSION['test1'] ;
$std->first = 'first';

3.php В третьем файле выводим

<?php
session_start();
print_r($_SESSION['test1']->first);

Что получим? Правильно

first

Хотя мы не записывали переменную std в Сессию, так как это объект, str ссылается на объект, который в сессии, и при изменение его, мы меняем этот же объект в сессии.

То же самое правильно для функции.

При передачи объекта в функцию, при модификации объекта в функции он изменяется и после нее.

 

 

 

Любимые фильмы

  1. Пассажиры / Passengers (2016)
  2. Остров / The Island (2005)
  3. Время / In Time (2011)
  4. Обливион / Oblivion (2013)
  5. Прометей / Prometheus (2012)
  6. Интерстеллар / Interstellar (2014)
  7. Марсианин / The Martian (2015)
  8. Гравитация / Gravity (2013)
  9. Жизнь Пи / Life of Pi (2012)
  10. Я, робот / I, Robot (2004) — самый дорогой фильм для меня, в плане $$$

Jquery chrome и не понятый баг.

В линуксе стоит довольно старый хром. Version 35.0.1916.153, хотя сейчас под винду актуальна 43 версия (что? 43, вот это они штампуют)
Так, вот странный глюк поймал, 
Мне нужно напротив каждого элемента, при наводке мышки выводить кнопочку,
сделал так

                    $(".pt10").hover(
                        function(){ //over
                            $(this).find(".send-message").show();
                        },
                        function(){ //out
                            $(".send-message").hide();
                        }
                    );


вроде все правильно, но хром показывает кнопку один раз, после чего больше не хочет выводить ее. В firefox все работает ок, выходит проблема врятли в коде, скорее в браузере,
и может в новой версии все хорошо. 
Но стоило добавить еще один div .test2, размером 0 на 0 px, как кнопка стала отображаться вновь, при наводке. 

                    $(".pt10").hover(
                        function(){ //over
                            $(this).find(".send-message").show();
                            $(this).find(".test2").show();
                        },
                        function(){ //out
                            $(".send-message").hide();
                            $(this).find(".test2").hide();
                        }
                    );

ps. после этого все же решил обновить хром в centos, и что? после этого все стало хорошо.

В линкусе он тоже 43 версии.

chrome

 

Интересно, если у другого пользователя будет хром старый, он получить этот баг, а как бы я о нем узнал, если бы работал под виндой и получал всегда свежее обновление. Не понятно.

 

Вытащить из яндекс список популярных страниц.

Была задача, составить список популярный страниц на сайте и вывести их как рекомендованные для пользователя.

На сайте стоит яндекс метрика, а яндекс через api предлагает получить список популярных страниц.

 

Написал две функции, которые справляются с поставленной задачей.

 

 

// отправляем запрос курлом
function getTokenYandex2($url,$peremen,$headers) {
    $post_arr=array();
    foreach ($peremen as $key=>$value) {
        $post_arr[]=$key."=".$value;
    }
    $data=implode('&',$post_arr);

    $handle=curl_init();
    curl_setopt($handle, CURLOPT_URL, $url);
    curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($handle, CURLOPT_POST, true);
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
    $response=curl_exec($handle);
    $code=curl_getinfo($handle, CURLINFO_HTTP_CODE);
    return array("code"=>$code,"response"=>$response);
}


function getInfoYandex($token){


    $startTime = strtotime(date('Y-m-d')." -1 month");
    $startTime=date("Ymd",$startTime);

    $ch = curl_init( 'http://api-metrika.yandex.ru/stat/content/popular?id=____ID___5&per_page=500&date1='.$startTime.'&date2='.date('Ymd', time()));

    // получать заголовки
    curl_setopt ($ch, CURLOPT_HEADER, 0);
    // если ведется проверка HTTP User-agent, то передаем один из возможных допустимых вариантов:
    curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3');
    // авторизация в яндекс по токену
    curl_setopt ($ch, CURLOPT_HTTPHEADER, array('Authorization: OAuth '.$token, 'Accept: application/x-yametrika+json', 'Content-Type: application/x-yametrika+json'));
    curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 10 );
    curl_setopt ($ch, CURLOPT_TIMEOUT, 10 );
    // возвращать результат работы
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    // не проверять SSL сертификат
    curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
    // не проверять Host SSL сертификата
    curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
    // следовать редиректу
    curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
    // выполнить запрос
    curl_exec ($ch);
    // получить результат работы
    $result = curl_multi_getcontent ($ch);

    return json_decode($result);

}


первая функция, getTokenYandex2 для получения токена, у вас должна быть учетка в яндекс метрике.
вторая функция getInfoYandex возвращает массив из списка популярных страниц.

 

Все это вызывается вот так:

 

 

// вызываем функцию получения токена
$result=getTokenYandex2("https://oauth.yandex.ru/token",
    array(
        'grant_type'=> 'password', // тип авторизации
        'username'=> '_____ВАШ__ЛОГИН________',
        'password'=>'______ВАШ_ПАРОЛЬ_____________',
        'client_id'=>'_____КЛИЕНТ_ID__ПОЛУЧАЕМ_В_ЯНДЕКС_API___________',
        'client_secret'=>'______ПОЛУЧАЕМ_В_ЯНДЕКС_API___________',
    ),
    array('Content-type: application/x-www-form-urlencoded','Connection: close')
);



$token=json_decode($result['response']);
// спрашиваем у яндекса, какие страницы популярны
$listPageYandex=GetInfoYandex($token->access_token);

в итоге у нас массив из популярных страниц, дальше находил эти страницы в bitrix и менял им вес.

PS. Список популярных страниц запрашивается за последний месяц.

 

 

PPS.

В начале я не понял, как получить токен автоматом. Везде на яндекс было написано, что пользователь вроде сам попадает на страницу авторизации яндекса, и там авторизуется, а тебе кэлбеком возвращается токен.

Замутил даже на сокете авторизацию :)

 

 

$sock=fsockopen('ssl://oauth.yandex.ru', 443);	// curl замена
$fields="grant_type=password&username=LOGIN&password=PASSWORD&client_id=400000000000000000000000000000&client_secret=4000000000000000000003";
$msg="POST /token HTTP/1.1\r\nHost: oauth.yandex.ru\r\nContent-Type: application/x-www-form-urlencoded\r\nConnection: close\r\nContent-Length: ".(strlen($fields))."\r\n\r\n".$fields."\r\n\r\n\r\n";
fwrite($sock, $msg);
$resp='';
while (!feof($sock)) {
    $resp.=fgets($sock, 128);
};
fclose($sock);
$arr=Array();
preg_match_all("/{.*?}/", $resp, $arr);
$json=json_decode($arr[0][0]);
var_dump($json);

Это в принципе работает, но курлом как то правильнее что-ли.
Тут кстати есть подводные камни, сервер яндекс все никак не хотел закрывать соединения, пока не добавил Connection: close.

Импорт в bitrix

Есть задачка, прочитать excel файл, напротив каждого региона есть запись. Нужно регион сопоставить с его ID в bitrix и дальше методом add добавить.

Написал такую функцию

 

 

function getNumberRegion($name){

    $arrayRegion=array(
        38285=>'Брянская область',
        38284=>'Владимирская область',
        38283=>'Волгоградская область',
        38282=>'Вологодская область',
        38281=>'Воронежская область',
        38280=>'Еврейская автономная область',
        38279=>'Ивановская область',
        38278=>'Иркутская область',
        38277=>'Калининградская облатсь',
        38276=>'Калужская область',
        38275=>'Кемеровская область',
        38274=>'Кировская область',
        38273=>'Костромская область',
        38272=>'Курганская область',
        38271=>'Курская область',
        38269=>'Липецкая область',
        38268=>'Магаданская область',
        38267=>'Москва',
        38265=>'Мурманская область',
        38264=>'Республика Адыгея',
        38263=>'Нижегородская область',
        38262=>'Республика Алтай',
        38261=>'Республика Башкортостан',
        38260=>'Новгородская область',
        38259=>'Новосибирская область',
        38258=>'Республика Бурятия',
        38257=>'Республика Дагестан',
        38256=>'Омская область',
        38255=>'Республика Ингушетия',
        38254=>'Кабардино-Балкарская республика',
        38253=>'Оренбургская область',
        38252=>'Орловская область',
        38251=>'Пензенская область',
        38250=>'Псковская область',
        38249=>'Ростовская область',
        38248=>'Рязанская область',
        38247=>'Самарская область',
        38246=>'Санкт-Петербург',
        38245=>'Саратовская область',
        38244=>'Сахалинская область',
        38243=>'Свердловская область',
        38242=>'Смоленская область',
        38241=>'Тамбовская область',
        38240=>'Тверская область',
        38239=>'Томская область',
        38238=>'Тульская область',
        38237=>'Тюменская область',
        38236=>'Ульяновская область',
        38235=>'Челябинская область',
        38234=>'Ярославская область',
        38233=>'Ханты-Мансийский автономный округ - ЮГРА',
        38232=>'Чукотский автономный округ',
        38231=>'Ямало-Ненецкий автономный округ',
        38230=>'Республика Калмыкия',
        38229=>'Карачаево-Черкесская республика',
        38228=>'Республика Карелия',
        38227=>'Республика Коми',
        38226=>'Республика Марий Эл',
        38225=>'Республика Мордовия',
        38224=>'Республика Саха (Якутия)',
        38223=>'Республика Северная Осетия-Алания',
        38222=>'Республика Татарстан',
        38221=>'Республика Тыва',
        38220=>'Удмуртская республика',
        38219=>'Республика Хакасия',
        38218=>'Чеченская республика',
        38217=>'Чувашская республика',
        38216=>'Забайкальский край',
        38215=>'Камчатский край',
        38214=>'Краснодарский край',
        38213=>'Красноярский край',
        38212=>'Пермский край',
        38211=>'Приморский край',
        38210=>'Ставропольский край',
        38209=>'Хабаровский край',
        38208=>'Амурская область',
        38207=>'Архангельская область',
        38206=>'Астраханская область',
        38190=>'Ленинградская область',
        38189=>'Белгородская область',
        38188=>'Алтайский край',
        38185=>'Московская область',
    );
    // в нижний регистр массив
    array_walk_recursive($arrayRegion, function (&$item, $key) { if (is_string($item)) $item = mb_strtolower($item); });
    return array_search(mb_strtolower(trim($name)),$arrayRegion,true);

}

function delc2a0($str){
    return str_replace("\xc2\xa0", '', $str);
}

 

подаем на функцию регион, он возвращает его номер,  ничего сложного.

PS функция delc2a0 для удаления мусора, когда читаем excel.

 

SOAP and BASE64

Потратил около часа, чтобы понять, почему при кодировании в base64 и передачи это через SOAP, получатель не может прочитать файл.

Оказалось все просто. SOAP сам упаковывает данные в BASE64 и конструкция

$imgbinary = fread(fopen($data['FormFileBuffer'], "r"), filesize($data['FormFileBuffer']));
 $base64File = base64_encode($imgbinary);

 

оказалась не нужна, достаточно сразу было отдать $imgbinary