Определение компьютер или мобильное устройство

<?php
/**
 * Определение компьютер или мобильное устройство
 * автор: waplog.net
 * 30.10.08
 */

/*в оригинальном скрипте ваплога (http://waplog.net/ru/html/faq.shtml)
есть один по моему мнению недочет: пустой юзер-агент считается мобилой
поэтому эта версия с доп условием !$h_ua
*/
$h_ua = str_replace('windows ce', '', strtolower($_SERVER['HTTP_USER_AGENT']));
if (
	!$h_ua ||
    strpos($h_ua, 'windows') !== false	||
	strpos($h_ua, 'linux') !== false	||
	strpos($h_ua, 'bsd') !== false		||
	strpos($h_ua, 'x11') !== false		||
	strpos($h_ua, 'unix') !== false		||
	strpos($h_ua, 'macintosh') !== false	||
	strpos($h_ua, 'macos') !== false)
{
	// it's computer - not show counter
} else {
	// it's mobile phone - show counter
	echo "your waplog counter code...";
}

/*
В целом, неплохой способ, пользуюсь сейчас им.
Я могу это утверждать, потому что перепробовал кучу разных методов :)
Единственный недостаток способа от ваплога: неучет мобильных устройств с платформой на линуксе. 
*/
?>
30 октября 2008, 19:51

Создание базы из дампа при помощи mysqli

<?php
/**
 * Создание базы из дампа при помощи mysqli
 * автор: Nc_Soft
 * 29.10.08
*/

/*
Часто бывает нужно загрузить sql-дамп, а в phpmyadmin лезть либо не хочется,
либо никак (с мобилы).
Что нам не хватает в обычном процедурном интерфейсе php-mysql?
Правильно, возможность совершить несколько запросов, разделенных ;
Сейчас я покажу как это сделать при помощи mysqli (разумеется, он должен быть на хостинге)
*/

//параметры доступа к бд
define('HOST','localhost');
define('USER','юзер');
define('DB','база');
define('PASS','пароль');

//коннектимся
$mysqli=new mysqli(HOST,USER,PASS,DB);
if (mysqli_connect_error()) die('access error');

//допустим, это файл дампа 
$dump='tables.sql';

//выполняем все запросы в дампе
$mysqli->multi_query(file_get_contents($dump));

//всё, база создана.
?>
29 октября 2008, 17:03

Определение принадлежности ip к диаппазону

<?php
/**
 * Определение принадлежности ip к диаппазону
 * автор: Nc_Soft
 * 28.10.08
 */

//пусть имеется диаппазон, допустим, Мегафона 83.149.0.0-83.149.7.255

//вспомогательная функция
function ext_ip2long($ip)
{
	return sprintf("%u",ip2long($ip));
}

//приведенный ip клиента
$ip=ext_ip2long($_SERVER['REMOTE_ADDR']);

//принадлежность
if (ext_ip2long('83.149.0.0')<=$ip && $ip<=ext_ip2long('83.149.7.255'))
{
	echo 'ip клиента принадлежит диаппазону';
}
else 
{
	echo 'ip клиента не принадлежит диаппазону';
}

/*
Почему же я стал городить доп-функцию, а не воспользовался
очевидным вариантом ip2long($ip) ?
Ответ в особенностях 32-битных систем:
echo ip2long('130.244.0.0') выдаст в 32 битной системе -2097938432
*/
?>
28 октября 2008, 01:38

Определение нагрузки сервера *nix (load averages)

<?php
/**
 * Определение нагрузки сервера (load averages)
 * автор: Nc_Soft
 * 13.10.08
 */

/*воспользуемся командой top, 
а чтобы можно было обработать вывод откроем канал*/
$la=popen('top','r');

//читаем первую строчку
$av=fgets($la);

//вытаскиваем текущую нагрузку (в %)
preg_match('|load averages:\s+(\d+\.\d+)|',$av,$arr);

//для порядка приводим к типу float
$average=(float)$arr[1];

//закрываем канал
pclose($f);

echo "текущая нагрузка: $average%";
?>
13 октября 2008, 10:13

Эффект "мокрого пола"

<?php
/**
 * Эффект "мокрого пола"
 * автор: MYPABEU (http://mypabeu.habrahabr.ru)
 * 30.09.08
 */

//путь к картинке
$img=imagecreatefrompng('c:/qqq.png');

//размер отраженного объекта в % от оригинала
$perc=50;

//максимальная прозрачность
$maxAlpha=120;

$src_height = imagesy($img);
$src_width = imagesx($img);
$dest_height = $src_height + ($src_height / (100/$perc));
$dest_width = $src_width;

$reflected = imagecreatetruecolor($dest_width, $dest_height);
imagealphablending($reflected, false);
imagesavealpha($reflected, true);

imagecopy($reflected, $img, 0, 0, 0, 0, $src_width, $src_height);
$reflection_height = $src_height / 2;
for($y=$src_height; $y<$dest_height; $y++)
{
	$alpha = (($y-$src_height)/($dest_height-$src_height))*$maxAlpha;

	for($x=0; $x<$src_width; $x++)
	{
		$rgba = imagecolorat($img, $x, $src_height - ($y-$src_height+1));
		$rgba = imagecolorsforindex($img, $rgba);
		$rgba = imagecolorallocatealpha($reflected, $rgba['red'], $rgba['green'], $rgba['blue'], $alpha);
		imagesetpixel($reflected, $x, $y, $rgba);
	}
}
$img = $reflected;

header('Content-type:image/png');
imagepng($img);

?>
30 сентября 2008, 15:53

Перекодировка из двухбайтового юникода в utf-8

<?php 
/** 
 * Перекодировка из двухбайтового юникода в utf-8 
 * автор: nc_soft 
 * 18.09.08 
 *  
 */ 

//может быть встречались с таким в j2me? 
$s='\u041f\u0440\u0435\u0432\u0435\u0434 \u041a\u0440\u0435\u0432\u0435\u0434\u043a\u043e!'; 

//чтобы перекодировать в нормальный вид можно пошаманить вот так 
echo preg_replace('#\\\\u([0-9a-f]{4})#se','iconv("UTF-16BE","UTF-8",pack("H4","$1"))',$s); 

/*надеюсь, кому-то пригодится, хотя эти заметки я пишу в основном для себя :)*/

//upd: способ номер 2
print_r( json_decode('["'.$s.'"]') );
18 сентября 2008, 18:07

Вычисление квадратного корня

<?php
/**
 * Вычисление квадратного корня
 * автор: Nc_Soft
 * 01.09.08
 */

//Задача: вычислить квадратный корень числа $n
$n=2;

//Конечно, можно воспользоваться стандартной функцией
echo sqrt($n);

/**
 * Но учитывая, что сегодня 1 сентября мы воспользуемся методом Ньютона — Рафсона :)
 */

//точность вычислений
$eps=0.0001;

//начальное приближение
$sqr = $n/2;

while (abs($sqr - ($n/$sqr)) > $eps) 
{
	$sqr = 0.5 * ($sqr + ($n/$sqr));
}

echo "<br />Квадратный корень из $n равен $sqr";
1 сентября 2008, 21:03

XSLT трансформация

<?php
/**
 * XSLT трансформация
 * автор: Nc_Soft
 * 19.07.08
 */

/*
пример трансформирует xml документ source.xml по шаблону
style.xsl
*/
$path_xml = "source.xml";
$path_style = "style.xsl";

// грузим XML документ
$xml = new DOMDocument;
$xml->load($path_xml);

//грузим шаблон
$xsl = new DOMDocument;
$xsl->load($path_style);

// создаем xslt обработчик
$proc = new XSLTProcessor;

//применяем таблицы
$proc->importStyleSheet($xsl);

//выводим результат
echo $proc->transformToXML($xml);

?>
19 июля 2008, 21:07

Оптимизация типов полей в таблице MYSQL

<?php
/**
 *Оптимизация типов полей в таблице MYSQL
 *автор: Nc_Soft
 *17.07.08
*/

/*
Для того, чтобы проверить, а оптимально ли вы подобрали типы полей есть 
очень полезный запрос (делайте в PhpMyAdmin или в прогах типа Navicat)
*/

SELECT * FROM table_name PROCEDURE ANALYSE();

/*
Анализировать желательно уже рабочую таблицу с заполненными данными, 
интересен прежде всего последний столбец, в котом система предлагает свои варианты
типов полей.
Естественно, это все имеет лишь рекоммендательный характер.
*/
17 июля 2008, 22:30

Перенаправление запросов к несуществующим файлам

#
# Перенаправление запросов к несуществующим файлам
# автор: nc_soft
# 04.07.08
#

#бывает удобно, когда запросы к несуществующим файлам 
#перенаправляются к какому-то определенному, на этом, кстати,
#и построена модель MVC

RewriteEngine on

RewriteBase / 

RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d

RewriteRule ^(.*)$ index.php/$1

#теперь все левые запросы пойдут в index.php c $SERVER['REQUEST_URI']
4 июля 2008, 11:21

3D Captcha

<?php
/**
 * 3D Captcha
 * автор: KAndy (http://kandy.habrahabr.ru/)
 * 30.07.08
*/

/*
Прочитал на хабрахабре интересный топик
http://habrahabr.ru/blog/php/45463.html
понравилась реализация 
капчи, все четко и ничего лишнего, в стиле ооп
*/
 
$capthca = new Capthca3d(); 
$capthca->render(); 


class Capthca3d{ 
    const CHARS = 'WEafRTYIPAGHJKXBNM3479j'; 
    protected $hypot = 8; 
    protected $image = null; 
     
    protected $text = ''; 
     
    public function __construct() 
    { 
        $this->time = microtime(true); 
        $this->generateCode(); 
     
    } 
    protected function generateCode() 
    { 
        $chars = self::CHARS; 
        for($i =0; $i<3; $i++){ 
            $this->text .= $chars{ mt_rand(0,22)}; 
        } 
    } 
     
    public function getText() 
    { 
        return $this->text; 
    } 
    protected function getProection($x1,$y1,$z1) 
    { 
        $x = $x1 * $this->hypot;  
        $y = $z1 * $this->hypot; 
        $z = -$y1 * $this->hypot; 
         
        $xx = 0.707106781187;  
        $xy = 0; 
        $xz = -0.707106781187;  
         
        $yx = 0.408248290464;  
        $yy = 0.816496580928;  
        $yz = 0.408248290464; 
         
        $cx = $xx*$x + $xy*$y + $xz*$z; 
        $cy = $yx*$x + $yy*$y + $yz*$z+ 20 * $this->hypot; 
        return array( 
            'x' => $cx, 
            'y' => $cy 
            );  
    } 
     
    function zFunction($x,$y){ 
        $z = imagecolorat($this->image,$y/2,$x/2)>0?2.6:0; 
        if( $z != 0 ){ 
            $z += mt_rand(0,60)/100; 
        } 
        $z += 1.4 * sin(($x+$this->startX)*3.141592654/15)*sin(($y+$this->startY)*3.141592654/15); 
        return $z; 
    } 
    public function render()     
    { 
        $xx =30; 
         $yy =60; 
         
         $this->image = imageCreateTrueColor($yy * $this->hypot  , $xx * $this->hypot); 
         
        $whiteColor = imageColorAllocate($this->image,255,255,255); 
        imageFilledRectangle($this->image,0,0,$yy * $this->hypot  , $xx * $this->hypot,$whiteColor); 
         
        $textColor = imageColorAllocate($this->image,0,0,0); 
        imageString($this->image, 5, 3, 0, $this->text, $textColor); 
         
         
         $this->startX = mt_rand(0,$xx);     
         $this->startY = mt_rand(0,$yy); 
         
         $coordinates = array(); 
          
        for($x = 0; $x < $xx + 1; $x++){ 
            for($y = 0; $y < $yy + 1; $y++){ 
                $coordinates[$x][$y] = $this->getProection($x,$y,$this->zFunction($x,$y)); 
             } 
         } 
          
        for($x = 0; $x < $xx; $x++){ 
            for($y = 0; $y < $yy; $y++){ 
                 $coord = array(); 
                 $coord[] = $coordinates[$x][$y]['x']; 
                 $coord[] = $coordinates[$x][$y]['y']; 
                  
                 $coord[] = $coordinates[$x+1][$y]['x']; 
                 $coord[] = $coordinates[$x+1][$y]['y']; 
                  
                 $coord[] = $coordinates[$x+1][$y+1]['x']; 
                 $coord[] = $coordinates[$x+1][$y+1]['y']; 
                  
                 $coord[] = $coordinates[$x][$y+1]['x']; 
                 $coord[] = $coordinates[$x][$y+1]['y']; 
                 
                $c = (int) ($this->zFunction($x,$y)*32); 
                $linesColor = imageColorAllocate($this->image, $c, $c, $c); 
                imageFilledPolygon($this->image, $coord, 4, $whiteColor); 
                imagePolygon($this->image, $coord, 4, $linesColor); 
             } 
         } 
         
        $textColor = imageColorAllocate($this->image,0,0,0); 
        imageString($this->image, 5, 3, 0, $this->text, $whiteColor); 
        imageString($this->image, 1, 3, 0, (microtime(true)-$this->time), $textColor); 
        header('Content-Type: image/png'); 
         
        imagepng($this->image); 
        imagedestroy($this->image); 
    } 
}

?>
30 июня 2008, 11:45

Проверка даты

<?php
/**
 * Проверка даты.
 * автор: Nc_Soft
 * 11.06.08
 */

/*для проверки корректности даты в формате ДД.ММ.ГГГГ ЧЧ:ММ
можно применить следующую функцию.
если знаете подобную из стандартных, то сообщите в комментах.
*/

function ext_check_date($data)
{
	//проверка формата
	$parse = date_parse ( $data );
	if ( $parse['error_count'] != 0 )
	return 0;

	//проверка по грегорианскому календарю
	if (!(checkdate($parse['month'], $parse['day'], $parse['year'])))
	return 0;

	return $data;
}

$data = '30.02.2008 12:59';
$data = ext_check_date($data);

if (!$data)
echo 'дата не верна';
?>
11 июня 2008, 18:30

Автоматическое подключение файлов к скриптам

# Автоматическое подключение файлов к скриптам
# автор: Nc_Soft
# 21.05.08

#часто бывает необходимо подключать одни и теже файлы
#чтобы не писать каждый раз include можно прописать в .htaccess

php_value auto_prepend_file c:\WebServers\home\snippets\www\verx.php 

#auto_prepend_file означает подключение до скрипта

php_value auto_append_file c:\WebServers\home\snippets\www\niz.php 

#auto_append_file означает подключение после скрипта
21 мая 2008, 20:09

Подсветка php кода с нумерацией строк

<?php
/**
 * Посветка php кода с нумерацией строк
 * автор: Nc_Soft
 * 21.05.08
 */

//файл для подсвечивания
$f=highlight_file('c:\WebServers\home\snippets\test.php',1);

/*
можно $f=highlight_string()
*/

//первая строка
$str=1;

//замена по регулярному выражению с функцией обратного вызова
$f=preg_replace_callback('|<br />|sU','stroka',$f);

//первая строчка + код
echo '<span style="background-color:black;color:white">01</span> '.$f;

function stroka($v)
{
     GLOBAL $str;
     $str++;
     
     return $v[0].'<span style="background-color:black;color:white">'.sprintf("%02d", $str).'</span> ';
}

?>
21 мая 2008, 16:23

Подсчет размера каталога с подкаталогами при помощи SPL

<?php 
/**
 * Подсчет размера каталога с подкаталогами при помощи PSL 
 * автор: Nc_Soft 
 * 20.05.08 
 */ 

//нам понадобится php5 с PSL

//путь к директории
$path='.';

//используем RecursiveDirectoryIterator
$files=new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path) );

//размер
$size=0;

foreach ($files as $element)
{
	//визуально контролируем
	echo $element.' '.$files->getSize($element)." <br />\n";
	
	//подсчет
	$size+=$files->getSize($element);
}

//выводим
echo $size;

//как видите, php5+PSL очень упрощают рутинные операции

?>
20 мая 2008, 15:10

Постраничный вывод из Mysql

<?php
/**
 * Постраничный вывод из Mysql
 * автор: Nc_Soft
 * 20.05.08
 */

/*
Для более удобного вывода нам потребуется класс навигатор
скачать его можно по ссылке
http://snippets.pp.ru/class/Navigator.class.txt
необходимо переименовать его рассширение в php и подключить к скрипту
*/

//полключаем навигатор
require_once('Navigator.class.php');

/*
пусть у нас такая таблица в БД
id | user | msg
*/

//общее число записей
$q=mysql_query(" SELECT count(*) FROM our_table ");
$all=mysql_result($q,0,0);

//если есть записи, то включаем навигатор

if ($all)
{
	//записей на страницу
	$pnumber=10;
	
	//создаем объект
	$n=new Navigator($all,$pnumber);
	
	//запрос
	$q=mysql_query("SELECT * FROM our_table LIMIT {$n->start()},$pnumber ");
	
	//выводим результаты
	while (false!==($res=mysql_fetch_assoc($q)))
	{
		echo '<div>';
		echo 'id = '.$res['id'].'<br />';
		echo 'user = '.$res['user'].'<br />';
		echo 'msg = '.$res['msg'];
		echo '</div>';
	}
	
	//печатаем навигацию
	echo $n->navi();
}

?>
20 мая 2008, 01:06

Клиентский сервер на Php

<?php
/*
* Клиентский сервер на Php
* прислано: Антон Крупников
* 12.05.2008
*/

### Для работы скрипта требуется установленная на хосте библиотека php_sockets и должен быть отключен безопасный режим (safe_mode off)
$host = "127.0.0.1"; // IP
$port = 80; // Порт
set_time_limit(0)or die("Error! Safe mode on.\n"); // работаем бесконечно
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n"); // создаём сокет
$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n"); // привязываем сокет
$result = socket_listen($socket, 3) or die("Could not set up socket listener\n"); // слушаем сокет
while($socket){ // Работаем пока $socket возвращает TRUE
$spawn = socket_accept($socket) or die("Could not accept incoming connection\n");
$input = socket_read($spawn, 1024) or die("Could not read input\n"); // Читаем сокет
echo $input; // выводим все, что прочли, в браузер
$output = "Hello, World!"; // Текст ответа
socket_write($spawn, $output, strlen ($output)) or die("Could not write output\n"); // Отправляем клиенту Hello, World!
socket_close($spawn); // Завершаем работу с клиентом
}
socket_close($socket); // Закрываем сокет
?>
12 мая 2008, 23:07

Защита файлов от просмотра браузером

#Запрет к определенному файлу
<Files config.php> 
  deny from all 
</Files>

#Запрет к группе файлов по рассширению
<Files "*.ini"> 
  deny from all 
</Files> 

#Запрет к нескольким типам файлов по рассширению
<Files ~ ".(inc|conf|cfg)$"> 
  deny from all 
</Files>
3 мая 2008, 13:29

Jad генератор

<?php
/**
 * Jad генератор
 * автор: Nc_Soft
 * 29.04.08
 */

/*
jar это zip архив, поэтому потребуется class PclZip
http://snippets.pp.ru/class/PclZip.class.txt
*/

require_once('PclZip.class.php');

//jar файл
$file='test.jar';

//создаем объект
$jar=new PclZip($file);

//то , что извлеч
$mf='META-INF/MANIFEST.MF';

$jad=$jar->extract(PCLZIP_OPT_BY_NAME, $mf, PCLZIP_OPT_EXTRACT_AS_STRING);

$jad=$jad[0]['content'];

/*
А вообще, можно извлечь манифест еще проще 
$jad = file_get_contents("zip://$file#META-INF/MANIFEST.MF");
*/

//далее надо приписать урл и размер в байтах
$jad.="\nMIDlet-Jar-Size: ".filesize($file)."\nMIDlet-Jar-URL: $file";

/*
всё, можно либо сохранять
file_put_contents('test.jad',$jad);
либо выдавать скриптом

header("Content-type: text/vnd.sun.j2me.app-descriptor");
header('Content-Disposition: ; filename=test.jad');

*/

?>
29 апреля 2008, 22:34

Вывод содержимого каталога с подкаталогами при помощи SPL

<?php
/**
 * Вывод содержимого каталога с подкаталогами при помощи SPL
 * автор: Nc_Soft
 * 28.04.08
 */

//нам понадобится php5 с PSL

//путь к директории
$path='.';

//используем RecursiveDirectoryIterator
$files=new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path) );

//выводим с учетом вложенности
foreach ($files as $element)
echo str_repeat('-',$files->getDepth())."$element <br />\n";

//как видите, php5+PSL очень упрощают рутинные операции

?>
28 апреля 2008, 19:16