gzip сжатие

<?php
/*
*gzip сжатие страницы
*автор: nc_soft
*27.12.07
*/

/*
для представления страницы в gzip необходимо определить:
1.поддерживает ли браузер сжатие (должно быть Accept-Encoding: gzip,deflate)
2.послать заголовок ( header("Content-Encoding: gzip") )

к счастью это все делается автоматически при вызове буферизации
*/

ob_start('ob_gzhandler',9);

/*
где 9 это уровень сжатия (максимальный)

больше ничего для сжатия делать не надо, просто продолжайте скрипт дальше
*/

?>
27 декабря 2007, 15:32

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

<?php
/*
*Отсчет времени с учетом морфологии
*автор: nc_soft
*15.12.07
*/

//расчетная дата (часы, минуты, секунды, день, месяц, год)
$dateTo=mktime(0,0,0,1,1,2008);

//смещение по часам у хостера (в примере смещение от московского равно нулю)
$timediff=$dateTo-time()-3600*0;

$oneMinute=60;
$oneHour=60*60;
$oneDay=60*60*24;
$dayfield=floor($timediff/$oneDay);
$hourfield=floor(($timediff-$dayfield*$oneDay)/$oneHour);
$minutefield=floor(($timediff-$dayfield*$oneDay-$hourfield*$oneHour)/$oneMinute);
$secondfield=floor(($timediff-$dayfield*$oneDay-$hourfield*$oneHour-$minutefield*$oneMinute));

$sDaysLeft=$dayfield;
$sDaysText = "дней";
$nDaysLeftLength =strlen($sDaysLeft);
$d_1=substr($sDaysLeft,-1,1);

if (substr($sDaysLeft,-2,1) != 1 && $nDaysLeftLength>1)
{
    if ($d_1 == 2 || $d_1== 3 || $d_1== 4)
    {
        $sDaysText = "дня";
    }
    elseif ($d_1== 1)
    {
        $sDaysText = "день";
    }
}
if ($nDaysLeftLength==1)
{
    if ($d_1==2 || $d_1== 3 || $d_1== 4)
    {
        $sDaysText = "дня";
    }
    elseif ($d_1== 1)
    {
        $sDaysText = "день";
    }
}

$sHoursLeft=$hourfield;
$sHoursText = "часов";
$nHoursLeftLength = strlen($sHoursLeft);
$h_1=substr($sHoursLeft,-1,1);
if (substr($sHoursLeft,-2,1) != 1 && $nHoursLeftLength>1)
{
    if ($h_1== 2 || $h_1== 3 || $h_1== 4)
    {
        $sHoursText = "часа";
    }
    elseif ($h_1== 1)
    {
        $sHoursText = "час";
    }
}

if ($nHoursLeftLength==1)
{
    if ($h_1== 2 || $h_1== 3 || $h_1== 4)
    {
        $sHoursText = "часа";
    }
    elseif ($h_1== 1)
    {
        $sHoursText = "час";
    }
}

$sMinsLeft =$minutefield;
$sMinsText = "минут";
$nMinsLeftLength = strlen($sMinsLeft);
$m_1=substr($sMinsLeft,-1,1);

if ($nMinsLeftLength>1 && substr($sMinsLeft,-2,1) != 1)
{
    if ($m_1== 2 || $m_1== 3 || $m_1== 4)
    {
        $sMinsText = "минуты";
    }
    else if ($m_1== 1)
    {
        $sMinsText = "минута";
    }
}

if ($nMinsLeftLength==1)
{
    if ($m_1== 2 || $m_1==3 || $m_1== 4)
    {
        $sMinsText = "минуты";
    }
    elseif ($m_1== "1")
    {
        $sMinsText = "минута";
    }
}

$sSecsLeft = $secondfield;
$sSecsText = "секунд";
$s_1=substr($sSecsLeft,-1,1);
$nSecsLeftLength = strlen($sSecsLeft);
if (substr($sSecsLeft,-2,1)!= 1 && $nSecsLeftLength>1)
{
    if ($s_1== 2 || $s_1== 3 || $s_1== 4)
    {
        $sSecsText = "секунды";
    }
    elseif ($s_1== 1)
    {
        $sSecsText = "секунда";
    }
}

if ($nSecsLeftLength==1)
{
    if ($s_1== 2 || $s_1== 3 || $s_1== 4)
    {
        $sSecsText = "секунды";
    }
    elseif ($sSecsLeft== "1")
    {
        $sSecsText = "секунда";
    }
}

$displaystring="До Нового Года осталось:\n".
$sDaysLeft." ".
$sDaysText." ".
$sHoursLeft." ".
$sHoursText." ".
$sMinsLeft." ".
$sMinsText." ".
$sSecsLeft." ".
$sSecsText;

if ($timediff<0) $displaystring='дата уже наступила';

echo $displaystring;

?>
16 декабря 2007, 02:13

собственный механизм сессий

<?php
/*
*Собственный механизм сессий
*автор: nc_soft
*25.11.07
*/


/*
далее перечислена библиотека функций, которая эмулирует поведение сессий.

поместим эту библиотеку в файл session.php
*/

// Открываем
function open($save_path, $session_name)
{
    // Сетевой адрес MySQL-сервера
    $dblocation = "localhost";
    // Имя базы данных
    $dbname = "boo";
    // Пользователь
    $dbuser = "root";
    // Его пароль
    $dbpasswd = "";

    // Устанавливаем соединение с базой данных
    $dbcnx = mysql_connect($dblocation,$dbuser,$dbpasswd);
    if (!$dbcnx) exit ("К сожалению, не доступен сервер MySQL : ".mysql_error());
    // Выбираем базу данных
    if (!@mysql_select_db($dbname,$dbcnx)) exit("К сожалению, не доступна база данных : ".mysql_error());

    //создаем таблицу в mysql (если она еще не создана)
    mysql_query("CREATE TABLE IF NOT EXISTS session (
   id_session int(11) NOT NULL auto_increment,
   session tinytext NOT NULL,
   putdate datetime NOT NULL default '0000-00-00 00:00:00',
   value tinytext NOT NULL,
   PRIMARY KEY  (id_session)
   ) TYPE=MyISAM;");

    return true;
}

function close()
{
    // Закрываем соединение с базой данных
    mysql_close();

    return true;
}

function read($id)
{
    // Читаем данные сессии
    $query = "SELECT value FROM session WHERE session = '$id'";
    $ses = mysql_query($query);
    if(!$ses) exit(mysql_error());
    $session = mysql_fetch_array($ses);

    // Возвращаем данные, помещённые в сессию
    return $session['value'];
}

function write($id, $sess_data)
{
    // Проверяем не зарегистрирована ли сессия
    // с таким именем
    $query = "SELECT COUNT(*) FROM session WHERE session = '$id'";
    $ses = mysql_query($query);
    if(!$ses) exit(mysql_error());
    if(mysql_result($ses,0) > 0)
    {
        // Такая сессия уже существует, необходимо
        // обновить время обращения к сессии
        $query = "UPDATE session SET putdate = NOW(),
                                   value = '$sess_data' 
                WHERE session = '$id'";
        if(!mysql_query($query)) exit(mysql_error());
        return false;
    }
    else
    {
        // Это первое обращение к сессии, необходимо
        // её зарегистрировать в базе данных
        $query = "INSERT INTO session
                VALUES (NULL,'$id', NOW(), '$sess_data')"; 
        $ses = mysql_query($query);
        if(!$ses) exit(mysql_error());
        return true;
    }
}

function destroy($id)
{
    // Удаляем сессию с идентификатором $id
    $query = "DELETE FROM session WHERE session = '$id'";
    if(!mysql_query($query)) exit(mysql_error());
    return true;
}

function gc($maxlifetime)
{
    // Выполняем "сборку мусора" - удаляем
    // старые записи
    $query = "DELETE FROM session
              WHERE putdate < NOW() - INTERVAL 20 MINUTE";
    if(!mysql_query($query)) exit(mysql_error());
    return true;
}

//говорим интерпритатору, что мы будем использовать свои функции для обработки сессий
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");

//старт сессии
session_start();

/*
на этом библиотечный файл session.php закончен, теперь просто инклудим его где требуется сессия
*/

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

/*
<?php
  //include "session.php";
  $_SESSION['name'] = "Имя";
  $_SESSION['surname'] = "Фамилия";
  
  print_r($_SESSION);
  echo '<a href="session.php">go</a>';
?>
*/

/*
Создано по материалам книги "Головоломки на PHP для хакера"
*/
?>
25 ноября 2007, 18:52

время генерации скрипта

<?php
/*
*Время генерации страницы
*автор: Сява
*10.11.07
*/

list($msec, $sec) = explode(chr(32), microtime());
$time = $sec + $msec;

/*
тут размещаете содержимое скрипта
*/
//это для примера
sleep(2);

list($msec, $sec) = explode(chr(32), microtime());
echo 'Генерация скрипта '.round(($sec + $msec) - $time, 4).' секунд'; 
//где 4 -это количество символов после запятой
?>
10 ноября 2007, 23:26

запись в файл данных из формы

<?php
/*
*ЗАПИСЬ В ФАЙл данных из формы
*автор: nc_soft
*10.11.07
*/

//переменная ошибок
$error=array();

//обработчик формы
if (!empty($_POST))
{
    //проверка параметра
    //функция str_replace() необходима чтобы вырезать переводы строк ( \n ) 
    $var=str_replace("\n",'',trim($_POST['var']));
    if (empty($var))
    $error['empty']='не введен параметр';
    

    //если все нормально пишем в файл
    if (empty($error))
    {
        //открываем
        $f=fopen('db.txt','a+');
        
        //блокируем
        flock($f,2);
        
        //запись с переводом строки
        fwrite($f,$var."\n");
        
        //закрытие
        fclose($f);
        
        /*переадресация , чтобы сбросить пост, это нужно чтобы при нажатии кнопки обновить 
         данные не добавились вновь*/
        header('Location: '.$_SERVER['SCRIPT_NAME'].'?ok=1');
        die();
    }
}

//если есть ошибки выводим
if (!empty($error))
echo '<p>'.implode('<br />',$error).'</p>';

if (isset($_GET['ok']))
echo '<p>данные записаны</p>';

//сама форма
?>
<form action="<?=$_SERVER['SCRIPT_NAME'];?>" method="post">
<p>
введите параметр:<br />
<input name="var" value="<?=isset($_POST['var']) ? htmlspecialchars(stripslashes(trim($_POST['var']))) : '';?>" /><br />
<input type="submit" value="отправить" />
</p>
</form>

<?php
/*
Примечания:

Для сбора ошибок используется именно массив, потому что удобно впоследствии выводить их через <br /> или списком, 
в ключе ммассива также можно указать причину $error['empty']='не введен параметр';

параметр value у input записан так, чтобы при ошибочном вводе получить в форме то, что ввел юзер, раздражают формы, 
когда пишешь, пишешь, ошибаешься в одном поле и все приходится вводить заново.

*/
?>
10 ноября 2007, 15:33

rss reader

<?php
/*
*RSS reader
*автор: nc_soft
*06.11.07
*/

//адрес канала новостей
$feed='http://www.webmoney.ru/rss.xml';

//грузим новости при помощи класса simplexml (нужна поддержка хостинга)
$sxml=simplexml_load_file($feed);

//атрибуты RSS протокола
foreach ($sxml->attributes() as $key=>$value)
{
    echo '<p>RSS '.$key.' '.$value.' </p>';
}

//заголовок
echo '<h2>'.$sxml->channel->title.'</h2>';

//выводим новости
foreach ($sxml->channel->item as $item)
{
    echo '<p style="background-color:#cccccc">';
    echo '<a href="'.$item->link.'">'.$item->title.'</a><br />';
    echo $item->description;
    echo '</p>';    
}

/*
пример взят из книги "Объектно-ориентированное программирование на PHP5"
Питер Ловэйн
*/

?>
6 ноября 2007, 22:29

генератор паролей

<?php
/*
*Генератор паролей
*автор: Mobnet
*21.10.07
*/

function gen_cod($num)
{
    //симвлы из которых генерируется пароль
    $kod=array(
    'a','b','c','d','e',
    'f','g','h','i','j',
    'k','l','m','n','o',
    'p','q','r','s','t',
    'u','v','w','x','y','z',
    'A','B','C','D','E',
    'F','G','H','I','J',
    'K','L','M','N','O',
    'P','Q','R','S','T',
    'U','V','W','X','Y','Z',
    '0','1','2','3','4','5',
    '6','7','8','9'
    );

    $ko='';
    for($i=1; $i<=$num; $i++)
    {
        $ko.=$kod[array_rand($kod)];
    }
    return $ko;
}

//применение функции
echo gen_cod(6);

/*
примечание:
в пароле ОЯЗАТЕЛЬНО должны присутствовать буквы разного регистра
 и цифры, для усложнения подбора, здесь же это не всегда выполняется
*/
?>
21 октября 2007, 14:00

вывод надписи на изображении ttf шрифтом

<?php
/*
*Вывод надписи на изображении ttf шрифтом
*автор: nc_soft
*12.10.07
*/

//текст в утф-8 (можно с переносом строки)
$text="выводимая \n строка";

//АБСОЛЮТНЫЙ путь к шрифту! например шрифт arial.ttf лежит в папке скрипта
$font=getcwd().'/arial.ttf';

//создаем изображение 100*100
$im = imagecreatetruecolor(100, 100);

//белый фон изображения
$white = imagecolorallocate($im, 255, 255, 255);

//цвет букв
$red = imagecolorallocate($im, 255, 0, 0);

//заливаем белым фоном
imagefilledrectangle($im, 0, 0, 100, 100, $white);

//наносим текст
imagettftext($im, 9, 0, 10, 20, $red, $font,$text);

/*
imagettftext ( 
идентификатор,
размер шрифта,
угол поворота,
начальная точка по Х,
начальная точка по У,
путь к шрифту,
текст )
*/

//выдача в браузер
header('Content-Type: image/jpeg');
imagejpeg($im);
?>
12 октября 2007, 00:25

запрет кэширования страниц

<?php
/*
*запрет кэширования страниц
*автор: nc_soft
*09.10.07
*/

//для 100% достижения эффекта необходимо послать все четыре заголовка!

Header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); //Дата в прошлом
Header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
Header("Pragma: no-cache"); // HTTP/1.1
Header("Last-Modified: ".gmdate("D, d M Y H:i:s")."GMT");

?>
9 октября 2007, 09:10

upload для opera mini

<?php
/*
*upload для opera mini
*08.10.07
*автор: DG-SC
*

оригинальный код и комментарии сохранены
*/
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Pragma" content="no-cache">
<title>Форма отправки файла для Opera Mini</title>
</head>

<body>

<!-- v1.1/13.10.2006-->
<?php

// путь для загруженных файлов, по аналогии с настоящей загрузкой по http
//$uploaddir = '\\home\\opera-mini.ru\\www\\test\\fileup\\';
$uploaddir = 'fileup/';
/*
//НИЖЕ ИДЁТ ЗАМЕНА ВОТ ТАКОГО БЛОКА ЗАГРУЗКИ
if (move_uploaded_file($_FILES['filel']['tmp_name'], $uploaddir . $_FILES['filel']['name'])) {
echo "File is valid, and was successfully uploaded<br>";
} else {
echo "There some errors!<br>";
}

*/
/*
прикрепление файла происходит в виде отсылки имени файла и его тела, кодированного в Base64.
в post для данного примера это выглядит как:

?file1=filename.extfile=/9...данные....Q
[POST: [имя файла ][сигн][данные файла ]]
как видно, здесь нет явного определения параметра file, поэтому этот параметр вырезается из всего POST.
всё, что до него - то имя, что после - данные.

*/
// определяем реальное имя файла
$uploadedfile = $_POST['file1'];

// проверка на наличие данных в POST
if (strlen($uploadedfile)) {
    // "вырезаем" данные файла из пришедшего
    // параметр 'file=' НЕ МЕНЯТЬ!!!! иначе не получите данных файла
    $array = explode('file=', $uploadedfile);
    $tmp_name = $array[0];
    $filebase64 = $array[1];
}

// проверка на нулевой размер файла
if (strlen($filebase64)) {
    // определяем имя файла для создания
    // ЗДЕСЬ МОЖНО ИЗМЕНИТЬ ДЛЯ ИСКЛЮЧЕНИЯ СОВПАДЕНИЙ C СУЩЕСТВУЮЩИМИ
    $name = $tmp_name;
    $FileName = $uploaddir.$name;

    // декодируем данные файла
    $filedata = base64_decode($filebase64);


    // создание и запись данных в файл
    $file = @fopen($FileName, "wb");

    if($file){
        if(flock($file, LOCK_EX)){
            fwrite($file, $filedata);
            flock($file, LOCK_UN);
        }
        fclose($file);
    }

    // отчёт о результате
    echo '<script language="Javascript">';
    if (file_exists($FileName) && filesize($FileName) == strlen($filedata)) {
        echo 'alert ("File ',$tmp_name,' is valid, and was successfully uploaded")';
    } else {
        echo 'alert ("An error occured while upload ',$tmp_name,'")';
    }
    echo '</script>';



    // просто список файлов в директории загрузки
    echo '..';

    foreach (glob($uploaddir.'*.*') as $filename) {
        $name = explode('/', $filename);
        //$name = explode('.', $name[1]);
        $lastmodif = filemtime($filename);
        $size = filesize($filename);
        $time = date("G:i j-M-Y", $lastmodif);

        echo "<br><a href=\"$filename\">$name[1] [$size] [$time]</a><br>";
    }


    echo '<p><a href="upload.php">upload</a></p>';

} else {
    // расположение формы на странице не критично.
    // единственное, что ссылка на обзор файла ДОЛЖНА БЫТЬ расположена
    // непосредственно под полем отображения имени файла "file1"
    echo '<form method="post" enctype="multipart/form-data">';
    echo 'Файл для отправки';
    ////////////////////////////////////////////////////////////////////////////////
    /// ФИКСИРОВАННАЯ ЧАСТЬ: НЕ ИЗМЕНЯТЬ!!!
    // имя менять при одновременной смене его и в обрабочике POST
    echo '<br><p> <input name="file1" value = ""> ';
    // url ссылки ДОЛЖЕН БЫТЬ именно таким, для определения Оперой
    // это "op:fileselect" НЕ МЕНЯТЬ!!! иначе Opera перестанет открывать ФМ для обзора
    echo '<a href="op:fileselect">Выбрать файл</a>';
    ////////////////////////////////////////////////////////////////////////////////
    echo '<br><p> <input type="submit" value="Послать файл">';
    echo '</form>';
}


?>

</body>
<!-- Created by DG-SC © 2006-->
</html>
8 октября 2007, 12:47

bash.org.ru rss граббер

<?php
/*
*bash.org.ru rss граббер
*автор: disable
*30.09.07
*/

//грузим rss файл
$data=file_get_contents('http://bash.org.ru/rss');

//обрабатываем
$dat=array();
preg_match_all('|<pubDate>(.+)</pubDate>|',$data,$dat);

$content=array();
preg_match_all('|<description><!\[CDATA\[(.+)\]\]></description>|',$data,$content);

//теперь у нас есть 2 массива по 100 элементов, воспользуемся постраничным выводом

//всего элементов
$all=count($content[1]);

//число сообщений на странице
$pnumber=5;

//номер страницы
$page=(isset($_GET['page'])) ? (int)$_GET['page'] : 1;

//число страниц
$num_pages=ceil($all/$pnumber);

//начальная позиция
$start=$page*$pnumber-$pnumber;

//проверка номера страницы
if ($page > $num_pages || $page < 1)
{
    $page=1;
    $start=0;
}

//посылаем заголовок
header('Content-type:text/html;charset=utf-8');

//выводим верх страницы (html код, выносим за <?php 
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>bash.org.ru</title>
</head>
<body>
<?php

//выводим цитаты
if ($all)
{
    for ($i=$start; $i<$start+$pnumber; $i++)
    {
        //if (!isset($dat[1][$i])) break;
        echo '<p style="border:1px solid;padding:2px">';
        echo $dat[1][$i];
        echo '<br />';

        //не забываем про утф-8
        echo iconv('windows-1251','utf-8',$content[1][$i]);

        echo '</p>';
    }

    //навигация
    echo '<p>';

    for($pr = '', $i =1; $i <= $num_pages; $i++)
    {
        echo $pr=(($i == 1 || $i == $num_pages || abs($i-$page) < 2) ? ($i == $page ? " [$i] " : ' <a href="'.$_SERVER['SCRIPT_NAME'].'?page='.$i.'">'.$i.'</a> ') : (($pr == ' ... ' || $pr == '')? '' : ' ... '));
    }

    echo '</p>';
}
else
{
    echo '<p>цитат нет</p>';
}

//закрываем теги
?>
</body>
</html>
30 сентября 2007, 04:00

как написать граббер

<?php
/*
*Как написать граббер.
*автор: nc_soft
*28.09.07
*/

/*
Любой граббер для удобства можно разделить на ТРИ оcновных части-этапа:
-получение
-обработка
-выдача

Получение.
Для того, что бы граббер нормально функционировал необходимо написать функцию для получнения
страницы с удаленного хоста по заданному url, надежнее пользоваться сокетами
(потому что библиотека CURL установлена не везде и не всегда, использовать file_get_contents()
и комбинации implode('',file(..)) конечно тоже можно, просто сокет предоставляет побольше возможностей.
Напишем функцию получния страницы по урл.
*/

function data($path,$host)
{
    /*
    $path путь к файлу скрипта, а так же передаваемые параметры
    $host сграббливаемый хост (например, sasisa.ru)
    */
    $fp = fsockopen($host, 80);
    if (!$fp)
    {
        die('ошибка');
    }
    else
    {
        $out = "GET $path HTTP/1.0\r\n";
        $out .= "Accept: image/gif, application/xhtml+xml, */*\r\n";
        $out .= "Accept-Language: ru\r\n";
        $out .= "Host: $host\r\n";

        //прикинемся оперой-мини
        $out .= "User-Agent: Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1716; ru; U; ssr)\r\n";

        $out .= "Cache-Control: no-cache\r\n";
        $out .= "Connection: Close\r\n\r\n";

        fwrite($fp, $out);
        $headers = "";

        while ($str = trim(fgets($fp)))
        $headers .= "$str\n";

        $body = "";

        while (!feof($fp))
        $body .= fgets($fp);
        fclose($fp);
    }
    //возвращаем данные
    return $body;
}

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

/*
function process($s)
{
Здесь сложно дать какие-то рекоммендации, все "грабберописание" состоит в основном в
придумывании этой функции, сделаем пока что "заглушку" на этом месте

return $s;
}
*/

/*
Для корректной работы грабба необходимо теперь правильно определять переменную $path, для примера давайте граббить
всем известный http://wen.ru/forum/index.php
пример очень характерный, потому что многие "потенциальные жертвы" грабов (загруз центры например)
состоят как раз из одного файла
*/

//с хостом определились
$host='wen.ru';

if (empty($_SERVER['QUERY_STRING']))
{
    //начальная позиция
    $path='/forum/index.php';
}
else
{
    //новые параметры
    $path='/forum/?'.$_SERVER['QUERY_STRING'];
}

/*
теперь необходимо зайти на страницу форума и посмотреть ее в коде
видно что ссылки выдаются так
<a href="/forum/?p=1&f=1&w=htm">Общение</a>
для работы грабба достаточно изменить ссылку так
<a href="index.php?p=1&f=1&w=htm">Общение</a>
что и сделаем в функции process
*/


/*function process($s)
{
$s=str_replace('<a href="/forum/','<a href="index.php',$s);
return $s;
}*/

//можно в принципе запускать :) (ПЕРВЫЙ ЭТАП)
$s=data($path,$host);

//обрабатываем (ВТОРОЙ ЭТАП)
$s=process($s);

//выдаем результат (ТРЕТИЙ ЭТАП)
/*
третий этап не так прост как кажется, если вы граббите загрузки, то
необходимо организовать переадресацию на прямую ссылку с контентом
*/
header('Content-type:text/html;charset=utf-8');
echo $s;

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

function process($s)
{
    $s=str_replace('<a href="/forum/','<a href="'.$_SERVER['SCRIPT_NAME'],$s);

    //смайлы
    $s=str_replace('<img src="','<img src="http://wen.ru/',$s);

    //копирайт
    $s=str_replace('</body>','<div>(c)snippets</div></body>',$s);

    return $s;
}

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

?>
28 сентября 2007, 12:21

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

<?php
/*
*вывод 5 случайных элементов из массива
*автор: nc_soft
*26.09.07
*/

//иммитация массива 1,2,3..100
$arr=range(1,100);

//новый массив с 5 случайными элементами
$new_arr=array_rand($arr,5);

//выводим элементы через <br />
echo implode('<br />',$new_arr);

/*этот пример может быть использован для вывода случайных ссылок из файла
и еще для кучи всяких дел :)*/

?>
26 сентября 2007, 22:11

автоопределение по браузеру wml или html

<?php
/*
*Автоопределение по браузеру wml/html
*Автор: Nc_Soft
*22.09.07
*/

//предлагаю свой способ, который был обкатан мною не раз ;)

if (strpos($_SERVER['HTTP_USER_AGENT'],'Profile/MIDP'))
{
	//МОБИЛА
}
elseif (strpos($_SERVER['HTTP_USER_AGENT'],'J2ME/MIDP'))
{
	//МОБИЛЬНЫЙ БРАУЗЕР НА J2ME
}
else
{
	//другое
}
?>
22 сентября 2007, 20:46

коды ответов http

<?php
/*
*коды ответов http
*автор: http://comp-info.ru/util/http.php
*22.09.07


Диапазон кодов Значение ответа 
100-199 Информационный 
200-299 Запрос клиента успешен 
300-399 Запрос клиента переадресован, необходимы дальнейшие действия 
400-499 Запрос клиента является неполным 
500-599 Ошибки сервера 

В HTTP в каждом диапазоне определены лишь несколько кодов, хотя для сервера при необходимости могут определяться собственные коды.
Клиент при получении кода, который он не может распознать, интерпретирует его в соответствии с диапазоном,
к которому этот код принадлежит.
Коды в диапазонах 100-199, 200-299 и 300-399 большинство Web-броузеров обрабатывают без извещения пользователя,
а некоторые коды ошибок из диапазонов 400-499 и 500-599 отображаются для пользователя (например, 404 Not Found).

Информационные ответы

Ответы в диапазоне 100-199 - информационные; они показывают, что запрос клиента принят и обрабатывается.


100 Continue
Начальная часть запроса принята, и клиент может продолжать передачу запроса. 

101 Switching Protocols
Сервер выполняет требование клиента и переключает протоколы в соответствии с указанием, данным в поле заголовка Upgrade. 



Успешные запросы клиента
Ответы в диапазоне 200-299 означают, что запрос клиента обработан успешно.


200 OK
Запрос клиента обработан успешно, и ответ сервера содержит затребованные данные. 

201 Created
Этот код состояния используется в случае создания нового URI.
Вместе с этим кодом результата сервер выдает заголовок Location, который содержит информацию о том, куда были помещены новые данные. 

202 Accepted
Запрос принят, но обрабатывается не сразу.
В теле содержимого ответа сервера может быть дана дополнительная информация о данной транзакции.
Гарантии того, что сервер в конечном итоге удовлетворит запрос, нет, даже несмотря на то,
что на момент приема запрос выглядел допустимым. 

203 Non-Authoritative Information
Информация в заголовке содержимого взята из локальной копии или у третьей стороны, а не с исходного сервера. 

204 No Content
Ответ содержит код состояния и заголовок, но тело содержимого отсутствует.
При получении этого ответа броузер не должен обновлять свой документ.
Обработчик чувствительных областей изображений может возвращать этот код,
когда пользователь щелкает на бесполезных или пустых участках изображения. 

205 Reset Content
Броузер должен очистить форму, используемую в данной транзакции, для дополнительных входных данных.
Полезен для CGI-приложений, требующих ввода данных. 

206 Partial ContentСервер возвращает лишь часть данных затребованного объема.
Используется в ответе на запрос с указанием заголовка Range.
Сервер должен указать диапазон, включенный в ответ, в заголовке Content-Range.



Переадресация



Код ответа в диапазоне 300-399 означает, что запрос не выполнен и клиенту нужно предпринять некоторые действия для удовлетворения запроса. 

300 Multiple Choices
Затребованный URI обозначает более одного ресурса.
Например, URI может обозначать документ, переведенный на несколько языков.
В теле содержи- мого, возвращенном сервером, может находиться перечень более конкретных данных о том, как выбрать ресурс правильно. 

301 Moved Permanently
Затребованный URI уже не используется сервером, и указанная в запросе операция не выполнена.
Новое местонахождение затребованного документа указывается в заголовке Location.
Во всех последующих запросах данного документа следует указывать новый URI. 

302 Moved Temporarily
Затребованный URI перемешен, но лишь временно. Заголовок Location указывает на новое местонахождение.
Сразу же после получения этого кода состояния клиент должен разрешить запрос при помощи нового URI,
но во всех последующих запросах необходимо пользоваться старым URI. 

303 See Other
Затребованный URI можно найти по другому URI (указанному в заголовке Location). Его следует выбрать методом GET по данному ресурсу. 

304 Not Modified
Это код ответа на заголовок lf-Modified-Since, если URI не изменялся с указанной даты. 
ело содержимого не посылается, и клиент должен использовать свою локальную копию. 

305 Use Proxy
Доступ к затребованному URI должен осуществляться через proxy-сервер, указанный в заголовке Location.



Неполные запросы клиента


Коды ответов в диапазоне 400-499 означают, что запрос клиента неполный.
Эти коды могут также означать, что от клиента требуется дополнительная информация. 

400 Bad Request
Означает, что сервер обнаружил в запросе клиента синтаксическую ошибку. 

401 Unauthorized
Этот код результата, передаваемый с заголовком WWW-Authenticate, показывает, что пославший запрос пользователь не имеет необходимых полномочий
и что при повторении запроса с указанием данного URI пользователь должен такие полномочия предоставить. 

402 Payment Required
Этот код в HTTP еще не реализован. 

403 Forbidden
Запрос отклонен по той причине, что сервер не хочет (или не имеет возможности) ответить клиенту. 

404 Not Found
Документ по указанному URI не существует. 

405 Method Not Allowed
Этот код выдается с заголовком Allow и показывает, что метод, используемый клиентом, для данного URI не поддерживается. 

406 Not Acceptable
Ресурс, указанный клиентом по данному URI, существует, но не в том формате, который нужен клиенту.
Вместе с этим кодом сервер выдает заголовки Content-Language, Content-Encoding и Content-Type. 

407 Proxy Authentication Required
Proxy-сервер должен санкционировать запрос перед тем, как пересылать его. Используется с заголовком Proxy-Authenticate. 

408 Request Time-out
Этот код ответа означает,
что клиент не передал полный запрос в течение некоторого установленного промежутка времени
(который обычно задается в конфигурации сервера) и сервер разрывает сетевое соединение. 

409 Conflict
Данный запрос конфликтует с другим запросом или с конфигурацией сервера.
Информацию о конфликте следует возвратить в информационной части ответа. 

410 Gone
Данный код показывает, что затребованный URI больше не существует и навсегда удален с сервера. 

411 Length Required
Сервер не примет запрос без указанного в нем заголовка Content-Length. 

412 Precondition Failed
Результат вычисления условия, заданного в запросе одним или несколькими заголовками if. . ., представляет собой "ложь". 

413 Request Entity Too Large
Сервер не будет обрабатывать запрос, потому что его тело слишком велико. 

414 Request-URI Too Long
Сервер не будет обрабатывать запрос, потому что его URI слишком длинный. 

415 Unsupported Media Type
Сервер не будет обрабатывать запрос, потому что его тело имеет неподдерживаемый формат.



Ошибки сервера



Коды ответов в диапазоне 500-599 показывают, что сервер столкнулся с ошибкой и, вероятно, не сможет выполнить запрос клиента. 

500 Internal Server Error
При обработке запроса на сервере один из его компонентов (например, CGI-программа) выдал аварийный отказ или столкнулся с ошибкой конфигурации. 

501 Not Implemented
Клиент запросил выполнение действия, которое сервер выполнить не может. 

502 Bad Gateway
Сервер (или proxy-сервер) получил недопустимые ответы другого сервера (или proxy-сервера). 

503 Service Unavailable
Данный код означает, что данная служба временно недоступна, но в будущем доступ к ней будет восстановлен.
Если сервер знает, когда это произойдет, может быть также выдан заголовок Retry-After. 

504 Gateway Time-out
Этот ответ похож на 408 (Request Time-out) , за исключением того, что шлюз или уполномоченный сервер превысил лимит времени. 

505 HTTP Version not supported
Сервер не поддерживает версию протокола HTTP, использованную в запросе.

*/

?>
22 сентября 2007, 14:00

обновляемый proxy лист

<?php
/*
*прокси-лист
*автор: nc_soft
*19.04.08
*/
?>


125.244.165.2:8080
125.245.30.250:8080
148.233.159.58:8080
155.136.224.10:80
190.24.128.210:8080
194.142.156.49:3128
195.229.236.106:80
200.165.160.98:8080
200.209.145.179:3128
200.220.142.11:3128
200.69.105.10:80
202.28.27.4:80
202.83.125.131:3128
203.252.46.115:80
210.158.6.201:8080
213.16.20.140:3128
218.249.83.87:8080
221.130.202.48:80
221.255.17.236:8080
222.47.88.14:3128
58.211.82.37:80
58.221.254.156:3128
81.189.106.138:8080
85.25.138.58:3128
91.74.160.18:8080
cache-mex-roma-2.uninet.net.mx:80
cache-mex-roma-2.uninet.net.mx:8080
echo397.server4you.de:3128
plum.amber.org.uk:3128
smb1-mq.mediaserv.net:3128
21 сентября 2007, 19:47

конвертор форматов изображений

<?php 
/*
*конвертор форматов изображений
*автор: nc_soft
*21.09.07
*/

//исходник
$source='kartinka.png';

//куда сохраняем
$destination='soxranyaem.gif';

//создаем изображение 
$img=imagecreatefrompng($source);

//сохраняем его в gif формате
imagegif($img,$destination); 

/*краткая запись
imagegif(imagecreatefrompng('kartinka.png'),'soxranyaem.gif')
соответственно, для других форматов используются другие графические функции
imagecreatefrompng
imagecreatefromjpeg
imagecreatefromgif
и
imagepng
imagegif
imagejpeg

ВНИМАНИЕ!!
при сохранении в формате jpeg необходимо учитывать, что у функции imagejpeg() ТРИ параметра, 
поэтому сохранять необходимо так
imagejpeg($img,'',$destination);
(средний параметр обозначает качество jpeg в процентах, но можно и не указывать)

спасибо wUPS.ru за поправку ;)
*/
?>
21 сентября 2007, 10:54

постраничная навигация в скриптах на файлах

<?php
/*
*постраничная навигация в скриптах на файлах
*автор: nc_soft
*18.09.07
*/

/*сгенерируем массив (для гостевой этот массив может быть получен как
file('gb.dat') )
в данном случаи проэмулируем его массивом 1,2,3...100 */
$arr=range(1,100);

//всего сообщений
$all=count($arr);

//число сообщений на странице
$pnumber=5;

echo '<p>всего элементов: '.$all.'</p>';

//номер страницы
$page=(isset($_GET['page'])) ? (int)$_GET['page'] : 1;

//число страниц
$num_pages=ceil($all/$pnumber);

//начальная позиция
$start=$page*$pnumber-$pnumber;

//проверка номера страницы
if ($page > $num_pages || $page < 1)
{
    $page=1;
    $start=0;
}

if ($all)
{
    //элементы выводятся в обратном порядке!!
    for ($i=$all-$start-1; $i>=$all-$start-$pnumber; $i--)
    {
        if (!isset($arr[$i])) break;
        echo '<p>';
        echo $arr[$i];
        echo '</p>';
    }

    //навигация
    echo '<p>';

    for($pr = '', $i =1; $i <= $num_pages; $i++)
    {
        echo $pr=(($i == 1 || $i == $num_pages || abs($i-$page) < 2) ? ($i == $page ? " [$i] " : ' <a href="'.$_SERVER['SCRIPT_NAME'].'?page='.$i.'">'.$i.'</a> ') : (($pr == ' ... ' || $pr == '')? '' : ' ... '));
    }

    echo '</p>';
}
else 
{
    echo '<p>элементов нет</p>';
}

?>
18 сентября 2007, 16:51

предпросмотр изображений

<?php
/*
*предпросмотр изображений
*автор: nc_soft
*15.09.07
*/

//путь к файлу картинки (jpg,gif,png)
$img='example.jpg';

$info=getimagesize($img);

//оригинальная ширина
$w_or=$info[0];

//оригинальная высота
$h_or=$info[1];

//тип
$type=$info['mime'];


//создаем изображение
$im1='';

if ($type=='image/jpeg')
$im1=ImageCreateFromJpeg($img);

if ($type=='image/gif')
$im1=ImageCreateFromGif($img);

if ($type=='image/png')
$im1=ImageCreateFromPng($img);

if (!$im1)
die('ошибка');

//далее условимся, что максимальный размер одной из сторон превьюшки равен 80 пикселей
//высчитаем коэффицент масштаба
if ($w_or>$h_or)
{
    $k=$w_or/80;
}
else
{
    $k=$h_or/80;
}

//высчитаем размеры превьюшки
$w=round($w_or/$k);
$h=round($h_or/$k);


//$im2=ImageCreate($w,$h); (если хотите ПЛОХОЕ качество картинки испоьзуйте эту функцию ;) )
$im2=imagecreatetruecolor($w,$h);

//ImageCopyResized($im2,$im1,0,0,0,0,$w,$h,$w_or,$h_or); (если хотите ПЛОХОЕ качество картинки испоьзуйте эту функцию ;) )
imagecopyresampled($im2,$im1,0,0,0,0,$w,$h,$w_or,$h_or);

if ($type=='image/jpeg')
{
    header('Content-type:image/jpeg');
    ImageJpeg($im2);
}
elseif ($type=='image/gif')
{
    header('Content-type:image/gif');
    ImageGif($im2);
}
elseif ($type=='image/png')
{
    header('Content-type:image/png');
    ImagePng($im2);
}
else die('ошибка');

?>
15 сентября 2007, 19:37

Определение числа файлов и их размер в папке произвольной вложенности

<?php
/**
 *Определение числа файлов и их размер в папке произвольной вложенности
 *автор: nc_soft
 *13.09.07
*/

//рекурсивная функция, которая вызывает сама себя
function count_files($directory)
{
    //нужна внешняя переменная чтобы учитывать суммарное кол-во файлов
    GLOBAL $i,$size;

    //открываем директорию
    $dir=opendir($directory);

    //читаем директорию в цикле
    while (false!==($file=readdir($dir)))
    {
        //если это файл, то
        if (is_file($directory.'/'.$file))
        {
            //увеличиваем счетчик
            $i++;

			//увеличиваем размер
			$size+=filesize($directory.'/'.$file);

            /*если необходимо, то можно удалить все файлы для примера вот так:
            unlink($directory.'/'.$file); */
        }
        //если же наткнулись на директорию
        elseif (is_dir($directory.'/'.$file) && $file!='.' && $file!='..')
        {
            //снова вызываем функцию уже для этой директории
            count_files($directory.'/'.$file);
        }
    }
    //закрываем директорию
    closedir($dir);
}

$i=0;
$size=0;

//посчитаем файлы в текущей директории
count_files('.');

echo 'файлов :'.$i;
echo ' размером :'.$size;

?>
13 сентября 2007, 23:54