Получение ip базы logofon

<?php
/**
 * Получение ip базы логофона
 * автор: Nc_Soft
 * 11.12.09
 */

//переменная содержащая время обновления базы
$GLOBALS['last_mod'] = '';

//открываем сеанс curl
$ch = curl_init('http://www.logofon.ru/xml/ips.xml');
curl_setopt($ch, CURLOPT_USERAGENT, 'snippets ip bot :)');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

//функция обратного вызова, которая будет проверять заголовки
curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'curlHeaderCallback');

//получение данных
$xml_data = curl_exec($ch);
//закрываем curl
curl_close($ch);

//функция обратного вызова, ищет Last-Modified
function curlHeaderCallback($ch, $header) {
	//чекаем Last-Modified
	$s = explode(': ', $header, 2);
	if ($s[0] == 'Last-Modified') $GLOBALS['last_mod'] = trim($s[1]);

	return strlen($header);
}

/*Имея $GLOBALS['last_mod'] в таком виде: Mon, 07 Dec 2009 21:43:14 GMT
мы можем проверять актуальность нашей базы, чтобы не обновляться лишний раз

для справки: чтобы получить timestamp надо сделать так
echo strtotime($GLOBALS['last_mod']);
*/

//допустим, надо обновиться, для этого парсим xml файл
//для примера выведу всех опсосов в табличках
//в качестве парсера юзаем правильные функции, а не регулярки!!!
$xml = simplexml_load_string($xml_data);

foreach ($xml->operator as $opsos) : ?>
	<hr />
	<table border="1">
	<tr>
	<td>ид</td>
	<td>опсос</td>
	<td>страна</td>
	<td>сокращение страны</td>
	</tr>
	
	<tr>
	<td><?=$opsos['id'];?></td>
	<td><?=$opsos['name'];?></td>
	<td><?=$opsos['country'];?></td>
	<td><?=$opsos['tld'];?></td>
	</tr>

	<?php
	//выводим диаппазоны
	foreach ($opsos->range as $range) : ?>
		<tr>
		<td colspan="2"><?=long2ip($range['ip1']);?></td>
		<td colspan="2"><?=long2ip($range['ip2']);?></td>
		</tr>
	<?php endforeach; ?>
	</table>
<?php endforeach;

/*
Как видите, все просто и удобно.
А при помощи этого сниппета можно легко импортировать
эту базу в свои проекты
*/
11 декабря 2009, 08:44

Применение Google Image Api

<?php
/**
 * Применение Google Image Api
 * автор: Nc_SOft
 * 25.11.09
 */

/*
Не знаю как вас, а меня изрядно подзаебали умники, продающие
"воздух" под громким названием глобальный поиск картинок
*/

$search = 'Сиськи Семенович';
$json = file_get_contents('http://ajax.googleapis.com/ajax/services/search/images?v=1.0&rsz=large&q='.urlencode($search).'&start=0');
$data = json_decode($json);

//смотрим с чем имеем дело 
//print_r($data); 
//и на вывод

?><div>результатов: <?=$data->responseData->cursor->estimatedResultCount;?></div>
<?php foreach ($data->responseData->results as $v) : ?>
<div><a href="<?=$v->unescapedUrl;?>"><img src="<?=$v->tbUrl;?>" /></a></div>
<?php endforeach; 

//для самостоятельной работы: 
//http://code.google.com/intl/ru/apis/ajaxsearch/documentation/reference.html#_intro_fonje
25 ноября 2009, 10:40

Определение номера телефона посетителя

<?php
/**
* Определение номера телефона посетителя
* автор: Nc_Soft
* 21.11.09
*/

//заголовки которые следует проверить

$phone_headers = array('HTTP_MSISDN',
                       'HTTP_X_MSISDN',
                       'HTTP_X_NOKIA_MSISDN',
                       'HTTP_X_WAP_NETWORK_CLIENT_MSISDN',
                       'HTTP_X_UP_CALLING_LINE_ID',
                       'HTTP_X_NETWORK_INFO');
$phone = '';

foreach ($phone_headers as $key) {
    if (isset($_SERVER[$key]) ) {
	    $arr = array();
        //находим нечто похожее на номер
        preg_match('`\d{5,20}`', $_SERVER[$key], $arr);
        if ($arr[0]) {
          $phone = $arr[0];
          break;
        }
    }
}

echo "номер - $phone";

//естественно, работает только у тех, кто лазает по вап профилю
21 ноября 2009, 23:11

Выдача удаленного файла скриптом с докачкой

<?php
/**
 * Выдача удаленного файла скриптом с докачкой
 * автор: Nc_Soft
 * 26.10.09
 */

//урл удаленного файла
$url = 'http://snippets.pp.ru/1.mp3';

//инициализация сеанса curl
$ch = curl_init($url);

//если клиент запрашивает докачку
if(isset($_SERVER['HTTP_RANGE'])) {
	curl_setopt($ch, CURLOPT_RANGE, str_replace('bytes=', '', $_SERVER['HTTP_RANGE']));
}

//бинарные данные
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);

//функция обратного вызова для заголовков (выдает такие же заголовки как и удаленный сервер)
curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'curlHeaderCallback');

//падаем в случаи ошибки
curl_setopt($ch, CURLOPT_FAILONERROR, 1);

//браузер
curl_setopt($ch, CURLOPT_USERAGENT, 'Opera/9.80 (Windows NT 5.1; U; ss; MRA 5.4 (build 02647); ru) Presto/2.2.15 Version/10.00');

//accept браузера
$info = array(
'Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1',
'Accept-Language: ru-RU,ru;q=0.9,en;q=0.8',
'Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1',
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $info);

//запуск
curl_exec($ch);

function curlHeaderCallback($ch, $strHeader) {
	//выдаем такой же заголовок, как и удаленный сервер, где лежит файл.
	//заголовки идут по порядку
	header($strHeader);
	return strlen($strHeader);
}

//запустив скрипт вы можете выдать удаленный файл через свой сайт.
//а чтобы файл нормально сохранялся, а не с адресом скрипта, 
//надо настроить mod_rewrite, чтобы на запрос блаблабла/file.mp3 выдавался этот скрипт
26 октября 2009, 03:58

Определение корректности кодировки

<?php
/**
 * Определение корректности кодировки
 * автор: Nc_Soft
 * 20.10.09
 */

/*
чтобы определить корректность кодивки 
могу порекомендовать вот такой способ
*/

$text = 'здесь текст';

if (!mb_check_encoding($text, 'utf-8')) {
	echo 'Символы некорректны для utf-8';
}

/*этот метод не определяет кодировку, но зато 
может определить когда она неверна*/
20 октября 2009, 19:02

Использование счетчика liveinternet.ru на wap сайте

<?php
/**
 * Использование счетчика liveinternet.ru на wap сайте
 * автор: Nc_Soft
 * 28.09.09
 */

/*
Думаю все встречали этот счетчик хоть раз в вебе.
При уёбищном дизайне он даёт отличные статистические данные по сайту, но
из-за ява скрипта в коде счетчика его использование на wap сайте не предоставляется возможным.
Давайте поправим эту оплошность

Оригинальный код счетчика можно получить на 
http://www.liveinternet.ru/code?nick=ВАШ_САЙТ

<!--LiveInternet counter-->
          <script type="text/javascript"><!--
document.write("<a href='http://www.liveinternet.ru/click' "+
"target=_blank><img src='http://counter.yadro.ru/hit?t52.5;r"+
escape(document.referrer)+((typeof(screen)=="undefined")?"":
";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?
screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+
";"+Math.random()+
"' alt='' title='LiveInternet: показано число просмотров и"+
" посетителей за 24 часа' "+
"border=0 width=88 height=31><\/a>")//--></script>
          <!--/LiveInternet-->

Теперь реализуем это всё без ява скрипта и наслаждаемся результатом
*/

echo '<a href="http://www.liveinternet.ru/click">
<img src="http://counter.yadro.ru/hit?t25.10;r'.urlencode($_SERVER['HTTP_REFERER']).';uhttp%3A//'.urlencode($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']).';0.'.rand(12345, 893855).'" alt="" /></a>';

//примечательно то, что нигде не фигурирует имя домена явно
28 сентября 2009, 00:10

Защита от sql инъекций

<?php
/**
 * Защита от sql инъекций
 * автор: Nc_Soft
 * 15.09.2009
 */

/*
Почему-то разработчики PHP не сделали функцию для работы с бд,
которая принимает запросы с параметрами.
Это сильно бы помогло в безопасности.
*/

//эта функция экранирует параметры
function qw() {
	$args = func_get_args();

	$query = array_shift($args);
	$args = array_map('mysql_real_escape_string', $args);
	array_unshift($args, $query);
	$query = call_user_func_array('sprintf', $args);
	
	if (!$query) die('неверный запрос');
	
	return mysql_query($query);
}

//пример использования
$q = qw("SELECT * FROM tbl WHERE login='%s' AND pass='%s' ", "лог'ин", "пар'оль");
//в этом запросе все кавычки будут экранированы, инъекция невозможна

/*вместо %s в функцию подставляется параметр, обработанный через mysql_real_escape_string
поэтому нет никакой необходимости предварительно обрабатывать данные , можно писать сразу
qw("SELECT FROM tbl WHERE id='%s' ", $_GET['id']);
Главное не забыть поместить %s в кавычки.
*/
15 сентября 2009, 20:13

Sitemap генератор для мобильных устройств при помощи simplexml

<?php
/**
 * Sitemap генератор для мобильных устройств при помощи simplexml
 * автор: Nc_Soft
 * 09.09.09
 */

/*
Пару слов зачем это нужно:
Позволяет ускорить индексацию поисковиками труднодоступных мест,
сообщая конкретные урл страниц.

http://www.google.com/support/webmasters/bin/answer.py?hl=ru&answer=34627
http://www.google.com/support/webmasters/bin/topic.py?topic=8493
*/

/*
Перейдем к реализации:
К примеру, имеется массив из 10 элементов, эмулирующий ид из бд
array(1, 2, ... , 10)
*/
$ids = range(1, 10);

//пусть каждому элементу соответствуем страница на сайте http://site.ru/$id.html

//собственно, генерация
$sitemap = simplexml_load_string('<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0"></urlset>');

foreach ($ids as $id) {
	$url = $sitemap->addChild('url');
	$url->loc = "http://site.ru/$id.html";
	$url->addChild('mobile', null, 'http://www.google.com/schemas/sitemap-mobile/1.0');
}

header('Content-type: text/xml; charset=utf-8');
echo $sitemap->asXML();

/*
Sitemap готов, сохраняете его как sitemap.php и добавляете в гугл как тут сказано
http://www.google.com/support/webmasters/bin/answer.py?answer=40348

также вы можете добавить доп.инфу в sitemap для каждой страницы
http://www.google.com/support/webmasters/bin/answer.py?answer=71936
*/
9 сентября 2009, 10:05

Мультипоточное скачивание через CURL

<?php
/**
 * Мультипоточное скачивание через CURL
 * 01.09.09
 * автор: Nc_Soft 
 */

//В php5 можно скачивать данные в несколько потоков

//инициализация
$ch1 = curl_init();
$ch2 = curl_init();

//адреса страниц (файлов) и опции
curl_setopt($ch1, CURLOPT_URL, 'kmx.ru');
curl_setopt($ch1, CURLOPT_HEADER, 1);
curl_setopt($ch2, CURLOPT_URL, 'wen.ru');
curl_setopt($ch2, CURLOPT_HEADER, 1);

//мульти загрузка
$mh = curl_multi_init();

//добавляем ресурсы в мультизагрузку
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);

//число запущенных загрузок
$running=null;

//грузим!
do {
	curl_multi_exec($mh, $running);
} while ($running > 0);


//освобождаем ресурсы и память
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);

?>
1 сентября 2009, 12:10

Получение представления таблицы mysql

<?php
/**
 * Получение представления таблицы mysql
 * автор: Nc_Soft
 * 31.08.09
 */

$q = mysql_query("SELECT * FROM tbl");

$thead = false;
echo '<table border="1">';
while (false !== $res=mysql_fetch_assoc($q)) {
	if ($thead === false) {
		$thead = true;
		echo '<tr>';
		foreach (array_keys($res) as $v) {
			echo '<td>'.$v.'</td>';
		}
		echo '</tr>';
	}

	echo '<tr>';
	foreach ($res as $ceil) {
		echo '<td>'.$ceil.'</td>';
	}
	echo '</tr>';
}
echo '</table>';
31 августа 2009, 15:19

Получение множественной формы русского слова

<?php
/**
 * Получение множественной формы русского слова
 * автор: Nc_Soft
 * 18.08.09
 * 
 */

/**
 * $n - число
 * $form1 - для одной штуки
 * $form2 - для двух штук
 * $form5 - для пяти штук
 */
function pluralForm($n, $form1, $form2, $form5) {
	$n = abs($n) % 100;
	$n1 = $n % 10;
	if ($n > 10 && $n < 20) return $form5;
	if ($n1 > 1 && $n1 < 5) return $form2;
	if ($n1 == 1) return $form1;
	return $form5;
}

//пример
echo '38 ' . pluralForm(38, 'попугай', 'попугая', 'попугаев');
?>
18 августа 2009, 12:54

Удаление пустых элементов из массива

<?php
/**
 * Удаление пустых элементов из массива
 * автор: Nc_Soft
 * 23.07.09
 */

/*встроенной функции, которая это делает вроде как не существует, 
но можно обойтись комбинацией их двух встроенных*/
$array = array('aa', 'bb', 'cc', '', 'dd', ' ', 3, 5, 'ee');

//вариант 1
$array1 = array_filter($array, 'trim');

//вариант 2
$array2 = array_diff($array, array('', ' '));

print_r($array1);
print_r($array2);
23 июля 2009, 21:47

Отображение php ошибок и предупреждений

/*
* Отображение php ошибок и предупреждений
* автор: Nc_Soft
* 19.07.09
*/

//в рабочем проекте это должно быть выведено в 0
php_value display_errors 1
php_value error_reporting 2047
19 июля 2009, 03:46

Исправление кодировки букв "ш" и "И" в MYSQL

/*
* Исправление кодировки букв "ш" и "И" в MYSQL
* автор: Nc_Soft
* 18.07.09
*/

/*
Частенько встречается при переносе бд, либо при шаманстве с кодировками
буквы "ш" и "И" оказываются битыми (речь идет о utf-8 конечно)
буква "ш" = chr(209).chr(63) / правильно chr(209).chr(136)
буква "И" = chr(208).chr(63) / правильно chr(208).chr(152)
Чтобы пофиксить делаем 2 запроса
*/

UPDATE `tbl` SET `pole` = REPLACE(
`pole`, 
CONCAT( CHAR(209), CHAR(63) ), 
CONCAT( CHAR(209), CHAR(136) )
);

UPDATE `tbl` SET `pole` = REPLACE(
`pole`, 
CONCAT( CHAR(208), CHAR(63) ), 
CONCAT( CHAR(208), CHAR(152) )
);
18 июля 2009, 22:31

Установка предопределенного значения autoincrement

<?php
/**
 * Установка предопределенного значения autoincrement
 * автор: Nc_Soft
 * 08.07.09
*/

/*
часто бывает нужно выставить вразумительно значение автоиндекса,
поэтому публикую запрос, чтобы не забыть
(в phpmyadmin: операции - параметры таблицы - AUTO_INCREMENT)
*/

mysql_query ("alter table tbl auto_increment=10");
?>
8 июля 2009, 04:15

Защита от прямых ссылок

# Защита от прямых ссылок
# автор: Nc_Soft
# 05.07.09
# Это позволит скачать ваш файл только с вашего сайта.
# надо создать вот такой .htaccess

RewriteEngine on
RewriteBase / 

# если надо разрешить скачку при пустом рефере раскомментируйте это
# RewriteCond %{HTTP_REFERER} !^$

# Дальше список идет набор разрешенных доменов
RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?snippets.pp.ru [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?wen.ru [NC]

# Форматы файлов, для которых устанавливается защита (например, mp3)
RewriteRule .(mp3)$ http://ya.ru

#Все запросы на http://snippets.pp.ru/1.mp3 перекинутся на http://ya.ru
5 июля 2009, 02:10

Google translate переводчик

<?php
/**
* Google translate переводчик
* автор: Nc_Soft, Soft_Land
* 22.06.09
*/

class GoogleTranslate {  
     
    static function translate($text, $source, $dest) { 
        $text    =    urlencode($text); 
        $ch        =    curl_init('http://translate.google.ru'); 
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
        curl_setopt($ch, CURLOPT_POST,1); 
        curl_setopt($ch, CURLOPT_POSTFIELDS, "text=$text&sl=$source&tl=$dest"); 
        curl_setopt($ch, CURLOPT_HEADER, 1); 
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.3) Gecko/2008092417'); 

        $r        =    curl_exec($ch); 

        $arr    =    array(); 
        preg_match("|<textarea name=utrans wrap=SOFT dir=\"ltr\" id=suggestion style=\"width:80%;margin:5px 0;overflow:auto\">(.*)</textarea>|sU", $r, $arr); 

        return strip_tags(str_replace('<br>', "\n", htmlspecialchars_decode($arr[1]))); 
    } 
     
}

echo GoogleTranslate::translate('Read this fucking manual', 'eng', 'ru');

//ps Спасибо SL за подробный языковой массив.
?>
22 июня 2009, 08:48

Вызов preg_replace_callback в классе

<?php
/**
 * Вызов preg_replace_callback в классе
 * автор: Nc_Soft
 * 11.06.09
 */

/* Рассмотрим на примере смайлов
условия: смайлов должно быть не более 3 в одном сообщении
смайлы вызываются как-то так :smile:
*/

class Smiles {
	//счетчик смайлов
	static $smc=0;

	//список смайлов
	static $smiles=array(
	'smile', 'hi', 'yes', 'bad', //итд
	);

	//функция печатающая текст (обратите внимание на callback вызов)
	static function pr($str) {
		return preg_replace_callback('`:([^\s]+):`U', array('self', 'cbs'), $str);
	}

	//функция обратного вызова для регулярного выражения
	//проверяет список смайлов и их количество
	static function cbs($v) {

		if (self::$smc<3) {
			if (in_array(strtolower($v[1]), self::$smiles)) {
				self::$smc++;
				return '<img src="/smiles/'.$v[1].'.gif" alt="'.$v[1].'"/>';
			}
		}

		return $v[0];
	}
}

//пример
echo Smiles::pr('Тут текст со смайлами (неверный смайл :error: )
:smile: :hi: :yes: :bad: ');
11 июня 2009, 17:04

Распаковка страницы в gzip

<?php
/**
 * Распаковка страницы в gzip
 * автор: Nc_Soft
 * 29.05.09
 * 
*/

//получаем страницу, где поддерживается сжатие
$ch=curl_init('http://snippets.pp.ru/');

//настраиваем, чтобы сеанс выводился не в браузер, а в переменную
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

//заголовки тут ни к чему
//curl_setopt($ch, CURLOPT_HEADER, 1);

//задаем заголовок для сжатия Accept-Encoding: gzip, deflate
//и еще несколько заголовков за компанию (необязательно)
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept-Encoding: gzip, deflate',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: ru,en-us;q=0.7,en;q=0.3',
'Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7',
));

//выполняем запрос
$res = curl_exec($ch);

//закрываем сеанс cURL
curl_close($ch);

//в переменной $res у нас сжатые данные в "кракозябрах", проверка
echo $res;

//разделитель для читабельности
echo "<br /><br />\n\n";

/*самое важное: чтобы раскодировать данные надо применить функцию
gzinflate, обрезав при этом первые 10 байт!*/
echo gzinflate(substr($res, 10));

/*
Результат можно увидеть запустив snippet.
Что нам это дает?
С серверов, где поддерживается сжатие можно тащить примерно в 10 раз
меньше данных, чем раньше, тоесть грабберы будут работать шустрее.

Ну и конечно, snippets не появляются из ниоткуда, 
каждый snippet решает проблему из "жизни", пример:
echo file_get_contents('http://radiorecord.ru/charts/');
Почему-то хоть убей выдается не вся страница, а примерно половина.
Запрос с использованием заголовка Accept-Encoding: gzip, deflate
позволяет получить страницу целиком, хоть и в сжатом виде.
*/
29 мая 2009, 03:02

Время в iso формате

<?php
/**
 * Время в iso формате
 * автор: Nc_Soft
 * 27.05.09
 */

/*Функция форматирует дату из бд (поле timestamp или datetime) в формат iso
с учетом временного сдвига.
Сдвиг отсчитывается от локального времени системы, а не по Гринвичу*/

function date_iso($data, $shift='+0') {
	
	$data=date('Y-m-d H:i:s', strtotime("$data $shift hour"));
	$p=date_parse($data);

	if ($p['error_count']) return ;

	static $m_collation=array(
	'января',
	'февраля',
	'марта',
	'апреля',
	'мая',
	'июня',
	'июля',
	'августа',
	'сентября',
	'октября',
	'ноября',
	'декабря',
	);

	return '<span class="time">'.$p['day'].' '.
	$m_collation[$p['month']-1].' '.
	$p['year'].', '.
	sprintf('%02d', $p['hour']).':'.sprintf('%02d', $p['minute']).'</span>';
}

echo '<br />Дата на пробу<br />';
echo date_iso('2009-05-27 01:53:32');

echo '<br />А теперь сдвинем на час вперед<br />';
echo date_iso('2009-05-27 01:53:32', '+1');

echo '<br />И на 3 часа назад<br />';
echo date_iso('2009-05-27 01:53:32', '-3');
27 мая 2009, 02:03