Сертификаты

Еще раз про сертификаты для сервера.

Если что то не выходит делаем следующие проверки.

1. ключ подходит с серитфикату.

Проверяем MD5 ключа и сертификата:

# openssl rsa -noout -modulus -in serov.1.key | openssl md5
(stdin)= 777711dbbab90e1b12e922bbdbde6716
# openssl x509 -noout -modulus -in serov.crt | openssl md5
(stdin)= 910a2dd2db8510094383563ed18c056d

Если строчки разные, то ключ не подходит к сертификату.

Ну и можно посмотреть что внутри

  • Check a Certificate Signing Request (CSR)
    openssl req -text -noout -verify -in CSR.csr
  • Check a private key
    openssl rsa -in privateKey.key -check
  • Check a certificate
    openssl x509 -in certificate.crt -text -noout

 

 

Сортировка данных в php

Например, у нас есть какой то набор данных, в stdClass. Он многомерный, и его надо сортировать, например по дате.
Делаем первое

array_walk_recursive($t, function(&$t) {return $t->date=strtotime($t->Created);});

Здесь мы создаем дополнительный элемент, к каждому набору записи, в которую записываем unix timestamp для сравнения.
Далее, сортируем набор данных по полю date

usort($t, function($a, $b){
return ($b->date - $a->date);
});

Не знаю, насколько это быстрее foreach или for, пока у меня не было несколько миллиардов записей, а до 1000 записей, существенной разницы не увидим.

Для более сложной сортировки, лучше использовать array_multisort, но это уже только для массива, хотя stdClass позволяет работать как с массивом.

Архивирование логов

Бывает так, что на машине остается ну например 5gb места, и все свободное место забито логами.

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

// переименовываем папку logs с текущей датой 
tar --remove-files -cvzf logs_03_11_2015.tar.gz logs_03_11_2015

 

После добавление файла в архив, он будет тут же удален.

 

Если совсем все плохо, и надо перетащить файлы на винте, где совсем нет место, можно сделать это по сети.

tar cvf - / | ssh -p2222 ted@8.8.8.8 "cat > archive.tar"

тут мы все что в корне отправляем на сервер 8.8.8.8 по 2222 порту под пользователем  ted

 

 

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

Тернарная условная операция или как часто любят говорить краткая запись 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 ссылается на объект, который в сессии, и при изменение его, мы меняем этот же объект в сессии.

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

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

 

 

 

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.