<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>DimoninG.ru &#187; на PHP</title>
	<atom:link href="http://dimoning.ru/category/dev/aboutphp/feed" rel="self" type="application/rss+xml" />
	<link>http://dimoning.ru</link>
	<description>программирование сайтов и скриптов</description>
	<lastBuildDate>Fri, 13 Jan 2012 22:38:37 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Как вытащить количество подписчиков в переменную из FeedBurner (PHP).</title>
		<link>http://dimoning.ru/kak-vyitaschit-kolichestvo-podpischikov-v-peremennuyu-iz-feedburner-php.html</link>
		<comments>http://dimoning.ru/kak-vyitaschit-kolichestvo-podpischikov-v-peremennuyu-iz-feedburner-php.html#comments</comments>
		<pubDate>Wed, 10 Mar 2010 21:50:38 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Скрипты PHP]]></category>
		<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=1463</guid>
		<description><![CDATA[Увидел я на одном блоге интересную штуку &#8211; не стандартный счетчик фидбернера, а подпись текстом: подписчиков столько-то. Заинтересовался. И понеслась.
Оказалось, что у FeedBurner&#8217;а есть свой API! Для нашего случая нужно знать следующее. Получить данные (в формате XML) можно по GET запросу http://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=[здесь название подписки].
Например, для этого блога запрос будет такой:
http://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=dimoning
На выходе получаем не сложное:
&#60;rsp stat=&#187;ok&#187;&#62;
&#60;feed [...]]]></description>
			<content:encoded><![CDATA[<p>Увидел я на одном блоге интересную штуку &#8211; не стандартный счетчик фидбернера, а подпись текстом: подписчиков столько-то. Заинтересовался. И понеслась.</p>
<p>Оказалось, что у FeedBurner&#8217;а есть свой API! Для нашего случая нужно знать следующее. Получить данные (в формате XML) можно по GET запросу http://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=[здесь название подписки].</p>
<p>Например, для этого блога запрос будет такой:</p>
<blockquote><p>http://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=dimoning</p></blockquote>
<p>На выходе получаем не сложное:</p>
<blockquote><p>&lt;rsp stat=&raquo;ok&raquo;&gt;<br />
&lt;feed id=&raquo;nktg1bcjqmq95fgqgj1q38o0l8&#8243; uri=&raquo;dimoning&raquo;&gt;<br />
&lt;entry date=&raquo;2010-03-09&#8243; circulation=&raquo;348&#8243; hits=&raquo;710&#8243; reach=&raquo;4&#8243;/&gt;<br />
&lt;/feed&gt;<br />
&lt;/rsp&gt;</p></blockquote>
<p>Распарсить это можно, как Вам удобнее. Я сделал простую регулярку:</p>
<blockquote><p>|circulation=\&raquo;([0-9]*)\&raquo;|si</p></blockquote>
<p>Итого, полностью код для получения количества подписчиков выглядит так:</p>
<blockquote><p>$blog = &laquo;snets&raquo;;<br />
$f = file_get_contents (&laquo;http://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=snets&raquo;);</p>
<p>preg_match (&laquo;|circulation=\&raquo;([0-9]*)\&raquo;|si&raquo;, $f, $m);<br />
echo $m[1];</p></blockquote>
<p>Само собой, на основе этого можно сделать и свою собственную иконку (с помощью, например, GD2). Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/kak-vyitaschit-kolichestvo-podpischikov-v-peremennuyu-iz-feedburner-php.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>XML SiteMap для WordPress (плагин)</title>
		<link>http://dimoning.ru/xml-sitemap-dlya-wordpress-plagin.html</link>
		<comments>http://dimoning.ru/xml-sitemap-dlya-wordpress-plagin.html#comments</comments>
		<pubDate>Sun, 04 Oct 2009 14:22:24 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[Ведем свой блог]]></category>
		<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=1418</guid>
		<description><![CDATA[Постовой: нужно купить майку? Лучший магазин!
Лично для меня всегда была больная тема &#8211; как создать sitemap.xml. В данном случае я буду говорить про WordPress. Как известно, лучше один раз четко разобраться в вопросе, чем постоянно его недопонимать и побаиваться :) Сайтмап нужен для индексации &#8211; Яндекс, Гугл, все понимают этот файл и он ускорит индексацию [...]]]></description>
			<content:encoded><![CDATA[<p><em>Постовой: нужно <a href="http://www.mayki-tut.ru/">купить майку</a>? Лучший магазин!</em></p>
<p>Лично для меня всегда была больная тема &#8211; как создать sitemap.xml. В данном случае я буду говорить про WordPress. Как известно, лучше один раз четко разобраться в вопросе, чем постоянно его недопонимать и побаиваться :) Сайтмап нужен для индексации &#8211; Яндекс, Гугл, все понимают этот файл и он ускорит индексацию сильно вложенных страниц. Кроме того, он поможет <a href="http://dimoning.ru/r.php?=http://www.sape.ru/r.HVlRirWNhE.php" target="_blank">сапе</a> понять, какие страницы на сайте.</p>
<p>В случае в WordPress все решается довольно просто &#8211; плагином. Я опишу как его установить.</p>
<p>Сначала <a href="http://dimoning.ru/r.php?=http://downloads.wordpress.org/plugin/google-sitemap-generator.3.1.6.zip" target="_blank">качаем плагин</a> из репозитория, так сказать. Распаковываем куда-нибудь и делаем несколько простых шагов:</p>
<p>1. Заливаем каталог с плагинов в wp-content/plugins, как обычно.<br />
2. Теперь вот &laquo;сложный&raquo; шаг. Создаем на своем компьютере два файла, называем их sitemap.xml и sitemap.xml.gz. Можно просто создать пустые текстовые документы и переименовать их. Заливаем эти файлы в корень блога (туда же, где файл wp-config.php). Теперь нужно установить на них права 666 (я лично поставил права 777). Это можно сделать с помощью FTP-клиента (в Far-Manager выбираем файл, жмем Ctrl + A и выставляем атрибуты; в CuteFTP правой кнопкой-&gt;права и так далее).<br />
3. Активируем плагин в админке.<br />
4. Открываем страницу настроек плагина в админке (обычно это Параметры -&gt; Имя Плагина). Жмем на ссылку &laquo;создать карту первый раз&raquo; (она вверху настроек). Если все хорошо, он создаст карту и запишет ее в файл sitemap.xml. Если появилась ошибка, скорее всего дело в правах на запись в этот файл.</p>
<p>Плагин обновляется автоматически! Как только происходит постинг нового поста, он добавляется в сайтмап, так что ничего больше делать не придется.</p>
<p>По поводу самого файла сайтмапы. Скачайте то, что сгенерировал плагин и посмотрите. Все становится очень понятно &#8211; куда нужно вписать URL, куда частоту обновления страницы и так далее.</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/xml-sitemap-dlya-wordpress-plagin.html/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Как скачать файл с другого сервера: fopen, cURL, wget</title>
		<link>http://dimoning.ru/kak-skachat-fayl-s-drugogo-servera-fopen-curl-wget.html</link>
		<comments>http://dimoning.ru/kak-skachat-fayl-s-drugogo-servera-fopen-curl-wget.html#comments</comments>
		<pubDate>Thu, 01 Oct 2009 13:25:13 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=1412</guid>
		<description><![CDATA[Постовой: не знаете как сдать нулевые отчетности? Rberg поможет!
Сегодня работал с одним скриптом, граббером. Ему нужно было закачивать файлы с удаленного сайта (изображения, если точнее) и класть их в каталог у себя на сайте. Я решил сделать заметку о способах закачки файлов. Есть несколько.
Первый. С помощью fopen, fread и прочего. Выглядит обычно так:
$fp = @fopen($sourceFileName, [...]]]></description>
			<content:encoded><![CDATA[<p><em>Постовой: не знаете как <a href='http://www.rberg.ru/services/26/'>сдать нулевые отчетности</a>? Rberg поможет!</em></p>
<p>Сегодня работал с одним скриптом, граббером. Ему нужно было закачивать файлы с удаленного сайта (изображения, если точнее) и класть их в каталог у себя на сайте. Я решил сделать заметку о способах закачки файлов. Есть несколько.</p>
<p>Первый. С помощью fopen, fread и прочего. Выглядит обычно так:</p>
<p>$fp = @fopen($sourceFileName, &laquo;rb&raquo;);<br />
$fd = @fopen($origFileName, &laquo;w&raquo;);<br />
if ($fp &amp;&amp; $fd) {<br />
while (!feof($fp)) {<br />
$st = fread($fp, 4096);<br />
fwrite($fd, $st);<br />
}<br />
}<br />
@fclose($fp);<br />
@fclose($fd);</p>
<p>То есть читаем исходный файл в бинарном режиме и сразу же пишем его в свой каталог.</p>
<p><strong>Второй.</strong> Через cURL. По сути это тот же способ, только с использованием cURL &#8211; подключаемся, читаем и копируем. При возможности лучше пользоваться вышеуказанным, он понятнее.</p>
<p>$ch = curl_init();<br />
curl_setopt($ch, CURLOPT_URL, $sourceFileName);<br />
curl_setopt($ch, CURLOPT_TIMEOUT, 300);<br />
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);</p>
<p>$st = curl_exec($ch);<br />
$fd = @fopen($origFileName, &laquo;w&raquo;);<br />
fwrite($fd, $st);<br />
@fclose($fd);</p>
<p>curl_close($ch);</p>
<p>То есть здесь для чтения используется cURL, а для записи все тот же стандартный метод.</p>
<p><strong>Третий.</strong> Почему-то никто никогда не использует команды Unix (или Windows, смотря какой сервер) для подобных операций. Причем на многих хостингах подобный подход не запрещен. Хотя, конечно, лучше было бы, если был бы свой VDS.</p>
<p>Все очень просто. Делаем следующее:</p>
<p>echo `wget http://site.ru/image.jpg`;</p>
<p>И всё. Картинка будет находиться в том же каталоге, откуда была вызывана команда. Можете погуглить и узнать о параметрах запуска. Не на каждом обычном хостинге получится ее применить, зато чертовски клаассно выглядит ;)</p>
<p><em>Постовой: Отличные <a href='http://www.prichesok.net/'>женские стрижки</a> по выгодным для мужей ценам ;)</em></p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/kak-skachat-fayl-s-drugogo-servera-fopen-curl-wget.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Что ни загрузка &#8211; разная RSS-иконка</title>
		<link>http://dimoning.ru/chto-ni-zagruzka-raznaya-rss-ikonka.html</link>
		<comments>http://dimoning.ru/chto-ni-zagruzka-raznaya-rss-ikonka.html#comments</comments>
		<pubDate>Thu, 27 Aug 2009 20:41:49 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[Общие советы]]></category>
		<category><![CDATA[на PHP]]></category>
		<category><![CDATA[на WordPress]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=1342</guid>
		<description><![CDATA[Продолжая тему маленьких полезных советов от программиста, хочу рассказать, как сделать, чтобы при каждом обновлении страницы Вашего блога появлялась новая иконка подписки (или шапка, например).
Сначала находим необходимое количество иконок (например, я нашел одну и перекрасил ее в 4 разных варианта). Назвать их все нужно одинаково, но чтобы в имени файла была цифра, благодаря которой они [...]]]></description>
			<content:encoded><![CDATA[<p>Продолжая тему маленьких полезных советов от программиста, хочу рассказать, как сделать, чтобы при каждом обновлении страницы Вашего блога появлялась новая иконка подписки (или шапка, например).</p>
<p>Сначала находим необходимое количество иконок (например, я нашел одну и перекрасил ее в 4 разных варианта). Назвать их все нужно одинаково, но чтобы в имени файла была цифра, благодаря которой они и отличаются. Например, я назвал свои вот так, банально:</p>
<p>rss1.jpg<br />
rss2.jpg<br />
и так далее до rss5.jpg</p>
<p><span id="more-1342"></span>Теперь идем в шаблон и смотрим, где у нас выводится иконка. У меня был вот такой код:</p>
<p>&lt;img src=&raquo;/rss1.jpg&raquo;&gt;</p>
<p>Его нужно заменить, добавив одну функцию из PHP: rand($from, $to). Эта функция возвращает случайное число от $from до $to. Например, rand (0, 10) вернет нам случайное число от 0 до 10 (включительно). Заменяем:</p>
<p>&lt;img src=&raquo;/rss&lt;?php echo rand(1, 5); ?&gt;.jpg&raquo;&gt;</p>
<p>То есть имя файла у нас будет генерироваться случайным образом (меняться цифра в названии). Если файлов больше или меньше, правим вторую цифру.</p>
<p><em>Постовой: <a href="http://www.ipoteka.irr.ru/" target="_blank">http://www.ipoteka.irr.ru/</a></em></p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/chto-ni-zagruzka-raznaya-rss-ikonka.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Движок блога для манимейкеров.</title>
		<link>http://dimoning.ru/dvizhok-bloga-dlya-manimeykerov.html</link>
		<comments>http://dimoning.ru/dvizhok-bloga-dlya-manimeykerov.html#comments</comments>
		<pubDate>Fri, 31 Jul 2009 14:23:17 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[Блогосфера]]></category>
		<category><![CDATA[Общее]]></category>
		<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=1264</guid>
		<description><![CDATA[Постовой: качественные юридические услуги в городе Москва.
Я уже очень редко пишу про манимейкинг, но теплые чувства к &#171;профессии&#187; испытываю. Пришла в голову идея написать движок блога специально для менимейкеров. Чем он будет отличаться? Во-первых, вообще говоря, вордпресс &#8211; движок не из легких. Все его навороты, вроде плагинов, сильно утяжеляют его. При этом он очень популярен [...]]]></description>
			<content:encoded><![CDATA[<p>Постовой: качественные <a href="http://www.advokats.ru/">юридические услуги</a> в городе Москва.</p>
<p>Я уже очень редко пишу про манимейкинг, но теплые чувства к &laquo;профессии&raquo; испытываю. Пришла в голову идея написать движок блога специально для менимейкеров. Чем он будет отличаться? Во-первых, вообще говоря, вордпресс &#8211; движок не из легких. Все его навороты, вроде плагинов, сильно утяжеляют его. При этом он очень популярен как для сателлитов, так и для самих блогов. Конечно, есть выход &#8211; сделать свою сборку, напичкать его плагинами, заранее отредактировать &laquo;что надо&raquo;. Но он все равно остается очень тяжелым (и по &laquo;весу&raquo; файлов и по базе данных тоже). Заливать неудобно, грузится иногда долго, хостинг &laquo;жрет&raquo; не слабо.</p>
<p>Что нужно от движка для манимейкеров?</p>
<p><span id="more-1264"></span></p>
<p>1) Чтобы был легкий. Несколько файлов. Нафиг сложные визуальные редакторы &#8211; все равно кроме &laquo;сделать жирым&raquo; или &laquo;подчеркнутым&raquo; или вставки ссылок ничем не пользуемся. Сделать простую структуру БД, а еще лучше &#8211; чтобы был на файлах. Одна запись &#8211; один файл в каталоге. Это существенно облегчит перенос с домена на домен (при продаже, например), больше того &#8211; исчезнут возможные проблемы с кодировкой БД.</p>
<p>2) Нужны встроенные средства разбиения на страницы. Я считаю, что ставить для этого плагин &#8211; верх идиотизма, могли бы уже и в сам ВП добавить такую функцию.</p>
<p>3) Сменные шаблоны дизайна. Еще лучше, чтобы понимал, например, разные шаблоны &#8211; от ВП, джумлы и чего-нибудь еще. Скачал, залил, включил, вот и все.</p>
<p>4) Собственный формат шаблона должен быть простым и понятным. В, опять же, ВордПрессе формат далеко непонятный. Чтобы узнать, какую функцию нужно использовать для вывода категорий и какие у нее параметры &#8211; это еще покопаться в документации надо. Еще лучше, чтобы все эти параметры (вроде &laquo;отображать у категорий количество постов в них или нет&raquo;) можно было задать из админки.</p>
<p>5) Чтобы по умолчанию ссылки в комментариях были закрыты от индексирования и чтобы для определенных ников комментаторов можно было открыть ссылки. Или для определенных комментариев.</p>
<p>6) Чтобы предлагаемые автором шаблоны были изначально направлены на СЕО.</p>
<p>7) Чтобы можно было нормально задать кейворды, тайтлы и дескрипшены для постов. В ВП такой возможности нет, плагины искать сложно.</p>
<p>8) Чтобы RSS сразу шла через FeedBurner.</p>
<p>9) Встроенные донейшн-бар (т.е. &laquo;пожертвования&raquo;). Говорят, работает неплохо.</p>
<p>10) Встроенные &laquo;красивые&raquo; URL.</p>
<p>11) Для сателлитов было бы классно &#8211; возможность сгенерировать теги для поста автоматически (над алгоритмом надо подумать).</p>
<p>12) Встроенная капча &laquo;Я не робот&raquo; не помешала бы. Ну или вообще какая-нибудь.</p>
<p>13) Я бы убрал регистрацию пользователей. Нафиг она в блоге, который ведет 1 человек или это вообще сателлит? Только ботов кормить.</p>
<p>14) Закрытая наглухо по IP админка, чтобы даже намека на подбор пароля нельзя было сделать.</p>
<p>15) Система доработок, в которой могут принять участие манимейкеры (согласованно придумать, что для него нужно дописать или изменить).</p>
<p>Самое интересное, что писать такой движок не долго. Но нужно хорошо продумать, что в нем должно быть. Ну и само собой, если он будет платный, то никуда не распространится, так что должен быть бесплатный.</p>
<p>Постовой: отличный <a href="http://www.lohovnet.ru/tyres/">обзор зимних шин</a>, пора подумать о &laquo;резине&raquo; уже осенью!</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/dvizhok-bloga-dlya-manimeykerov.html/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Сила MD5: почему MD5 и как применять на практике</title>
		<link>http://dimoning.ru/sila-md5-pochemu-md5-i-kak-primenyat-na-praktike.html</link>
		<comments>http://dimoning.ru/sila-md5-pochemu-md5-i-kak-primenyat-na-praktike.html#comments</comments>
		<pubDate>Sun, 26 Apr 2009 15:04:45 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[Общее]]></category>
		<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=1054</guid>
		<description><![CDATA[Меня иногда спрашиваю, а в чем крутость MD5? На кой черт нужно шифровать пароли этим хешем?
Отвечаю. Предположим, что злоумышленник нашел дырку в нашем сайте. Чтобы было серьезнее, предположим, что он нашел доступ к базе данных и может прочитать пароли всех пользователей (но перезаписывать базу данных он не может; так часто бывает).
Что происходит, если пароли лежат [...]]]></description>
			<content:encoded><![CDATA[<p>Меня иногда спрашиваю, а в чем крутость MD5? На кой черт нужно шифровать пароли этим хешем?</p>
<p>Отвечаю. Предположим, что злоумышленник нашел дырку в нашем сайте. Чтобы было серьезнее, предположим, что он нашел доступ к базе данных и может прочитать пароли всех пользователей (но перезаписывать базу данных он не может; так часто бывает).</p>
<p>Что происходит, если пароли лежат в открытом виде? Понятно: он берет любой логин и пароль и заходит под ними, делает гадости. Что происходит, если пароли зашифрованы двунаправленным шифрованием (это когда можно зашифровать и другим скриптом расшифровать)? Так как обычно тоже применяются стандартные алгоритмы, взломщик помучается, но расшифрует пароль. Что происходит, если пароль зашифрован с помощью md5? Взломщик видит хэш, но ничего сделать не может. Это однонаправленный метод шифрования.</p>
<p>Небольшая справка. Что такое однонаправленное шифрование? Это когда слово шифруется по какому-то алгоритму, а расшифровать его обратно нельзя &#8211; слишком моного возможных комбинаций или другая причина.</p>
<p>Как применять md5 на практике? Когда пользователь регистрируется и первый раз вводи пароль, в базу мы записываем его MD5-хеш. Ну скажем так:</p>
<p>$login = $_POST['login'];<br />
$hash = md5($_POST['password']);<br />
mysql_query (&laquo;INSERT INTO table VALUES (0, &#8216;$login&#8217;, &#8216;$hash&#8217;);&raquo;)</p>
<p>Теперь, когда пользователь заходит в свой аккаунт, нужно проверять хеш из базы с хешем введенного пароля, который мы создаем &laquo;на лету&raquo;. Например так:</p>
<p>$login = $_POST['login'];<br />
$pass = $_POST['password'];<br />
$user = mysql_fetch_array (mysql_query (&laquo;SELET * FROM table WHERE login=&#8217;$login&#8217;;&raquo;));<br />
if ($user['hash'] == md5($pass)){ /* вошли успешно */}</p>
<p>Конечно, я тут не проверял входящие данные и не проверял ошибки. Кстати, MySQL <a href="http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html#function_md5" target="_blank">тоже понимает MD5</a>, поэтому код выше можно переписать так, оставив только запрос:</p>
<p>$login = $_POST['login'];<br />
$pass = $_POST['password'];<br />
$user = mysql_fetch_array (mysql_query (&laquo;SELET * FROM table WHERE login=&#8217;$login&#8217; AND hash=MD5(&#8216;$pass&#8217;);&raquo;));</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/sila-md5-pochemu-md5-i-kak-primenyat-na-praktike.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Универсальная партнерская ссылка с любой страницы сайта</title>
		<link>http://dimoning.ru/universalnaya-partnerskaya-ssyilka-s-lyuboy-stranitsyi-sayta.html</link>
		<comments>http://dimoning.ru/universalnaya-partnerskaya-ssyilka-s-lyuboy-stranitsyi-sayta.html#comments</comments>
		<pubDate>Thu, 16 Apr 2009 01:39:11 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[Общее]]></category>
		<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=1038</guid>
		<description><![CDATA[Откладывая в сторону сиськи и возвращаясь к моему предпоследнему посту, хочется написать еще один, раз уж пошла такая пьянка.
Как работают партнерские программы мы все знаем: ставим свои ссылочки, по ним приходят покупатели, оплачивают товарчеги и мы получаем денежги на свой счетег. Ссылки обычно имеют вид site.ru/?p=10, где 10 &#8211; это наш ID.
Как правило можно поставить [...]]]></description>
			<content:encoded><![CDATA[<p>Откладывая в сторону <a href="http://dimoning.ru/idem-dalshe-no-uzhe-s-adaltom.html" target="_blank">сиськи</a> и возвращаясь к моему <a href="http://dimoning.ru/title-description-keywords-universalnaya-sistema-dlya-sayta.html" target="_blank">предпоследнему посту</a>, хочется написать еще один, раз уж пошла такая пьянка.</p>
<p>Как работают партнерские программы мы все знаем: ставим свои ссылочки, по ним приходят покупатели, оплачивают товарчеги и мы получаем денежги на свой счетег. Ссылки обычно имеют вид site.ru/?p=10, где 10 &#8211; это наш ID.</p>
<p>Как правило можно поставить партнерскую ссылку на любой товар, например site.ru/tovari/rozoviy_slon.htm?p=10 или на другую страницу.</p>
<p>А как программируются такие ссылки? Обычно предполагается, что ссылка будет передаваться через GET-запрос и находить мы ее будем в глобальном $_GET-массиве.</p>
<p>Но я предлагаю решение круче, которое позволит нам не зависеть от передачи параметра через GET-запросы и ставить партнерскую ссылку на любую страницу сайта. Интересно как?</p>
<p>В самом мега-главном файле сайта index.php в самом верху (после инициализации движка, точно так же как и в случае с <a href="http://dimoning.ru/title-description-keywords-universalnaya-sistema-dlya-sayta.html" target="_blank">tkd</a>), пишем следующее:</p>
<p>preg_match (&laquo;/(.*?)?p=([0-9]+)/si&raquo;, $_SERVER["REQUEST_URI"], $m);<br />
if (!empty ($m[2])) $pid = $m[2];</p>
<p>if (!empty ($pid)){<br />
setcookie (&laquo;partner&raquo;, $pid, time()+3600*24*7, &laquo;/&raquo;);<br />
}<br />
Как видно из кода, мы опять использовали REQUEST_URI. Напомню, что он содержит URL данной страницы (там где сейчас юзер) без http и домена сайта. Например такой: /hello.htm. С помощью регулярных выражений мы вырезаем из URI выражение вида ?p=x, и определяем этот x (переменная $pid). Причем тут автоматически идет и защита от злых дядек &#8211; если после ?p= идут не цифры, то ничего мы не получим.</p>
<p>Дальше, понятное дело, на Ваше усмотрение. У меня ставится кука с ID партнера, который привел пользователя на сайт.</p>
<p>И, таким макаром, мы можем добавить ?p= вообще в любую ссылку, движку теперь просто все равно куда мы ее добавляем &#8211; вырезается все с помощью регулярок.</p>
<p>Кстати, раскрываю секрет фирмы. $pid не имеет никакого отношения к <span style="text-decoration: line-through;">пидарасам</span> мужчинам нетрадиционной сексуальной ориентации. Расшифровывается в данном случае как partner id. В линуксе, например, pid означает как правило process id и так далее.</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/universalnaya-partnerskaya-ssyilka-s-lyuboy-stranitsyi-sayta.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>title / description / keywords &#8211; универсальная система для сайта</title>
		<link>http://dimoning.ru/title-description-keywords-universalnaya-sistema-dlya-sayta.html</link>
		<comments>http://dimoning.ru/title-description-keywords-universalnaya-sistema-dlya-sayta.html#comments</comments>
		<pubDate>Wed, 15 Apr 2009 02:29:25 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[Движки, CMS]]></category>
		<category><![CDATA[Общее]]></category>
		<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=1030</guid>
		<description><![CDATA[В последнем моем проекте было разработано довольно много разнообразных модулей (таких как опросы, новости, партнерские программы, разнообразная статистика, партнерские материалы, товары разных типов, да и просто страницы меню).
Возник вопрос о том, что для каждой страницы надо как-то задавать title, description и keywords (для SEO). Нужно было быстро реализовать это решение.
Обычно в таких случаях разработчики добавляют [...]]]></description>
			<content:encoded><![CDATA[<p>В последнем моем проекте было разработано довольно много разнообразных модулей (таких как опросы, новости, партнерские программы, разнообразная статистика, партнерские материалы, товары разных типов, да и просто страницы меню).</p>
<p>Возник вопрос о том, что для каждой страницы надо как-то задавать title, description и keywords (для SEO). Нужно было быстро реализовать это решение.</p>
<p>Обычно в таких случаях разработчики добавляют новые поля в базу данных для всех этих модулей, меняют скрипты (запросы в базы данных) и вообще перерабатывают пол-движка. Понятно, подводный камень в этом случае в том, что очень легко что-то пропустить, забыть подправить какой-то запрос и получить в релизе ошибки. А если, например, эти таблицы используют какие-то другие скрипты, то они могут внешне работать без ошибок, но фактически коверкать все данные (например, подсчитывать совершенно неверную статистику).</p>
<p>За 0.0141 секунды раздумий я придумал следующую систему, которая позволяет не перерабатывать весь движок.</p>
<p>Понятно, что каждая страница сайта имеет свой URL. URI &#8211; это тот же URL, только без домена. Его можно получить из переменной $_SERVER["REQUEST_URI"]. Понятно, что для каждой страницы URI свой собственный (иначе это уже одна и та же страница).</p>
<p>И возникает очень простая система. Создаем таблицу в БД с полями &laquo;title, key, descr, uri&raquo;. В том месте, где должны выводиться title, description и keywords пишем что-то вроде:</p>
<p>&lt;?php<br />
$uri = $_SERVER["REQUEST_URI"];<br />
if ($uri == &laquo;/index.php&raquo;) $uri = &laquo;/&raquo;;<br />
$q = mysql_query (&laquo;SELECT * FROM table WHERE uri=&#8217;$uri&#8217;;&raquo;);<br />
if (mysql_num_rows ($q) &gt; 0){<br />
$str = mysql_fetch_array ($q);<br />
$t = $str['title']; $k = $str['key']; $d = $str['descr'];<br />
}<br />
?&gt;<br />
&lt;meta name=&raquo;keywords&raquo; content=&raquo;&lt;?php echo $k; ?&gt;&raquo; /&gt;<br />
&lt;meta name=&raquo;description&raquo; content=&raquo;&lt;?php echo $d; ?&gt;&raquo; /&gt;<br />
&lt;title&gt;&lt;?php echo $t; ?&gt;&lt;/title&gt;</p>
<p>Понятно, что в таблицу записывается заголовок, описание и ключевики для того адреса, для которого мы хотим задать их. И работать это будет для всех страниц, которые обрабатывает движок (то есть в данном случае &#8211; для всего сайта вообще). А администратор получает возможность задавать заголовки, ключи и описание даже для тех страниц, которые в ТЗ не предусмотрены, плюс в следующих модулях не нужно будет реализовывать &laquo;внутреннюю&raquo; поддержку title, keywords и description.</p>
<p>Конечно, не забудьте о безопасности! Проверяйте это выражение перед передачей его в базу. Обычно оно проверяется очень просто &#8211; нельзя использовать никакие символы, кроме слеша, точки, букв и цифр.</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/title-description-keywords-universalnaya-sistema-dlya-sayta.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Автоматическое высчитывание количества дней до цели/события (PHP) &#8211; идея для манимейкеров</title>
		<link>http://dimoning.ru/avtomaticheskoe-vyischityivanie-kolichestva-dney-do-tselisobyitiya-php-ideya-dlya-manimeykerov.html</link>
		<comments>http://dimoning.ru/avtomaticheskoe-vyischityivanie-kolichestva-dney-do-tselisobyitiya-php-ideya-dlya-manimeykerov.html#comments</comments>
		<pubDate>Wed, 18 Mar 2009 14:27:44 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[на PHP]]></category>
		<category><![CDATA[на WordPress]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=961</guid>
		<description><![CDATA[Реклама: копии часов интернет магазин, работа киев, смета скачать
Манимейкерам очень может помочь такая штука. Например, мы поставили цель выйти на какой-то доход за 5 месяцев. Конечно, первая мысль: &#171;ууу, 5 месяцев, это много, я все успею!&#187;. Врят ли, с таким подходом.
Как видно из прошлого поста, сегодня мне кто-то в задницу воткнули шило, пока я спал, [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>Реклама: <a href="http://wwwomen.com.ua/watches/">копии часов интернет магазин</a>, <a href="http://kiev.netbee.ua/">работа киев</a>, <a href="http://www.expertsoft.com.ua/smeta/119/">смета скачать</a></p></blockquote>
<p>Манимейкерам очень может помочь такая штука. Например, мы поставили цель выйти на какой-то доход за 5 месяцев. Конечно, первая мысль: &laquo;ууу, 5 месяцев, это много, я все успею!&raquo;. Врят ли, с таким подходом.</p>
<p>Как видно из прошлого поста, сегодня мне кто-то в задницу воткнули шило, пока я спал, не иначе. Я поставил себе цель, и вынес в боковую колонку информацию о ней.</p>
<p>Наряду с обычной информацией о том, что за цель, сроки начала и конца, я сделал дополнительные поля. Первое &#8211; это состояние. Чего сейчас добился? Например по спорту у меня по нулям вообще. По деньгам тоже довольно печально (тут, правда, я еще не подсчитывал, сколько чего и где я зарабатываю, но наверняка не сильно больше, чем написал сейчас).</p>
<p>А третья вещь, которую я вообще ни у кого не видел, это <strong>автоматическое определение количества дней до окончания цели</strong>.</p>
<p>То есть блоггер сам заходит в свой блог и видит&#8230; Ага, мне осталось 7 дней до <span style="text-decoration: line-through;">звонка</span> окончания цели, нужно скорее что-то делать.</p>
<p>Реализуется на PHP за 1 минуту. Код следующий:</p>
<p>echo abs(gregorianToJD(&laquo;03&#8243;, &laquo;18&#8243;, &laquo;2010&#8243;)  &#8211; gregorianToJD(date(&laquo;m&raquo;), date(&laquo;d&raquo;), date( &laquo;Y&raquo;)));</p>
<p>Так вот реализовано у меня. Дата конца цели вписывается вместо 03, 18, 2010 (как понятно, 03 &#8211; месяц, 18 &#8211; день, 2010 &#8211; год конца цели). Текущая дата вычисляется автоматически. Значение на всякий случай берется по модулю (т.к. иногда может оказаться по сути верным, но с другим знаком).</p>
<p>Для WordPress все просто: в файле sidebar.php (или где хотите напечатать количество дней до цели) ставим этот код в тегах &lt;?php и ?&gt;.</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/avtomaticheskoe-vyischityivanie-kolichestva-dney-do-tselisobyitiya-php-ideya-dlya-manimeykerov.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Как следить за выполнением скриптов на PHP и управлями ими в длинных циклах</title>
		<link>http://dimoning.ru/kak-sledit-za-vyipolneniem-skriptov-na-php-i-upravlyami-imi-v-dlinnyih-tsiklah.html</link>
		<comments>http://dimoning.ru/kak-sledit-za-vyipolneniem-skriptov-na-php-i-upravlyami-imi-v-dlinnyih-tsiklah.html#comments</comments>
		<pubDate>Wed, 11 Mar 2009 01:36:30 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=937</guid>
		<description><![CDATA[Реклама: виды гвоздик, платья Allure Diagonal, способы похудеть
Возможно, Вам приходилось когда-то писать скрипты, где совершалось какое-то долгое и нудное действие. Ну например &#8211; грабился сайт или создавалось 10000 картинок с вотермарками. И вот ведь какое дело &#8211; совершенно непонятно, там вообще что-нибудь работает или все повисло? Особенно это тяжело, когда скрипт находится на стадии тестирования. [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>Реклама: <a href="http://www.vashsad.ua/rus/useful_clauses_459.html">виды гвоздик</a>, <a href="http://lanovale.com/html/diagonal.htm">платья Allure Diagonal</a>, <a href="http://ultra-effect.com/">способы похудеть</a></p></blockquote>
<p>Возможно, Вам приходилось когда-то писать скрипты, где совершалось какое-то долгое и нудное действие. Ну например &#8211; грабился сайт или создавалось 10000 картинок с вотермарками. И вот ведь какое дело &#8211; совершенно непонятно, там вообще что-нибудь работает или все повисло? Особенно это тяжело, когда скрипт находится на стадии тестирования. Может быть он пошел по замкнутому кругу (ну скажем начал обрабатывать фотографии заново), а мы не в курсе?</p>
<p>Я сейчас дописывал паука, который просто ползает по одному и тому же сайту (наподобие того, который у гугла или яндекса, только гораздо скормнее). Понятно, мне тестировать его тяжело &#8211; а вдруг он по одним и тем же ссылкам полез? А я не знаю? Или еще что-нибудь этакое, залез, например, на внешний сайт по ошибке и по нему пошел? И я придумал два способа для управления и слежения за подобного рода скриптами.</p>
<p><strong>Итак, мониторинг.</strong> У меня там все просто &#8211; паук знает ссылки, которые еще не обошел и количество страниц, которое уже обошел, две переменные.</p>
<p>Создаем функцию а-ля</p>
<p>function logit($msg){<br />
$file = @fopen (&laquo;log.txt&raquo;, &laquo;w&raquo;);<br />
@fwrite ($file, $msg);<br />
@fclose ($file);<br />
}</p>
<p>И в нашем &laquo;мега-цикле&raquo; вызываем logit ($var1.$var2); &#8211; все. Обе переменные записались в файл. А это значит, что я могу открыть его через браузер и лицезреть в реальном времени прогресс обхода (переменные var1 и var2 изменяются и записываются в файл). Жми F5, да радуйся.</p>
<p>Например, мой паучОк обошел мой же блог за 2 минуты и нашел 450 страниц (в Яше 400, в гугле 240) и я лицезрел меняющиеся цифры в такой вот строчке: &laquo;done: 450, fifo: 0, time: 130.87 sec&raquo; (это для примера, я не о пауках конкретно)</p>
<p><strong>Дальше, управление.</strong></p>
<p>Немного продолжаю свою мысль. Понятно, что когда скрипт &laquo;ушел&raquo; в работу, то мы уже можем не дергаться &#8211; никакие кнопки и прочие шаманства в браузере работать не будут (даже аякс, скрипт-то в &laquo;бесконечном&raquo; цикле).</p>
<p>А что, если использовать другой файл как шлюз для общения со скриптом? Ну например, скрипт во время выполнения записывает прогресс в вышеприведенный файл, а из другого периодически читает &#8211; что ему нужно делать. Если файл пустой, то скрипт спокойно выполняется. А если в файле появилась запись stop, например, то скрипт аварийно завершается (выход из цикла или вообще exit). Плюс к этому можно создать другой скрипт, скрипт-повелитель :), при запуске которого основной скрипт (у меня &#8211; паук) будет останавливаться.</p>
<p>Я имею ввиду, вот запустил я crawler.php. Он там чего-то делает, я не знаю что. Я могу даже браузер закрыть, т.к. от этого процесс не завершится, а я уже останусь вообще без контроля. Но есть чудо скрипт stop.php, я запускаю его, он пишет в какой-то файл типа gate.txt слово &laquo;stop&raquo;, а crawler.php этот файл периодически проверяет и если находит такое слово &#8211; прекращает работать.</p>
<p>Кстати, я раньше думал, что если нажать &laquo;стоп&raquo; в браузере &#8211; скрипт тоже остановится. Хрен, как бы не так. Он будет работать, пока не сделает все, что надо. А если он войдет в бесконечный цикл, то он не остановится. Так что достаточно запустить 50 таких скриптов и можно перезагружаться смело.</p>
<p>Такие вот идеи в 4.35 утра.</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/kak-sledit-za-vyipolneniem-skriptov-na-php-i-upravlyami-imi-v-dlinnyih-tsiklah.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Как написать граббер</title>
		<link>http://dimoning.ru/kak-napisat-grabber.html</link>
		<comments>http://dimoning.ru/kak-napisat-grabber.html#comments</comments>
		<pubDate>Thu, 18 Dec 2008 10:26:11 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=739</guid>
		<description><![CDATA[Хочу рассказать вам о том, как написать граббер. Напишем простой граббер на PHP, который грабит, нууу&#8230; скажем заголовок (title) страницы и записывает нам в базу данных. Таким образом не сложно написать любой граббер, который можно вмонтировать в любой движок. Когда я писал этот пост, у меня было постоянное дежавю. А дело в том, что недавно [...]]]></description>
			<content:encoded><![CDATA[<p>Хочу рассказать вам о том, как написать граббер. Напишем простой граббер на PHP, который грабит, нууу&#8230; скажем заголовок (title) страницы и записывает нам в базу данных. Таким образом не сложно написать любой граббер, который можно вмонтировать в любой движок. Когда я писал этот пост, у меня было постоянное дежавю. А дело в том, что недавно я написал статью о том, <a href="http://dimoning.ru/back-counter-1.html" target="_blank">как сделать собственный счетчик</a>. Но основные моменты там очень похожи, поэтому советую прочитать и ту статью тоже.</p>
<p>Любой граббер состоит из нескольких кусков:</p>
<p>1. подключение к странице-донору<br />
2. скачивание исходного кода<br />
3. вытаскивание нужного фрагмента (самый сложный этап)<br />
4. запись вытащенного фрагмента в базу данных/файл или куда-то еще</p>
<p><span id="more-739"></span></p>
<p>Между первым и вторым этапом возможен этап &laquo;обход защиты&raquo;. Иногда сервер проверяет реферера и другую информацию, чтобы удостовериться, что Вы не робот. Но как правило такие защиты обходятся &laquo;на раз&raquo; отправкой заголовка серверу с (опять же) нужной ему информацией.</p>
<p><strong>1. Подключение к странице-донору.</strong></p>
<p>В PHP есть несколько способов сделать это. Я покажу самый простой. Теоретически он работает не везде (иногда на хостинге запрещен этот метод), но я еще такого хостинга не видел. Например, подключаемся к блогам яндекса:</p>
<pre><code>
$sock = fopen ('http://blogs.yandex.ru/top/?page=1', 'r');
if (!$sock){
echo "Не получилось подключиться к yandex.";
}else{
}
fclose ($sock);
</code></pre>
<p>То есть мы открываем страницу, будто это обычный файл! Легко и приятно. Если страница не открылась, нам покажет ошибку, а если открылась, исполнится код в else.</p>
<p><strong>2. Чтение исходника.</strong></p>
<p>Дальше нужно прочитать исходный код страницы. Опять же не сложно. В цикле читаем всю информацию:</p>
<pre><code class="php">
else{
    $html = '';
    while (!feof($sock)){
        $html .= fgets($sock);
    }
}
</code></pre>
<p>Соответственно исходник страницы у нас будет в $html, а вывести его можно с помощью htmlspecialchars ($html).</p>
<p>3. Вытаскивание нужного фрагмента.</p>
<p>Это самый сложный момент во всей программе. Дело в том, что для его осуществления нужно знать регулярные выражения PHP. Изучить подробнее их можно <a href="http://www.google.ru/search?hl=ru&amp;q=%D1%80%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D0%B5+%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F+php&amp;btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA+%D0%B2+Google&amp;lr=&amp;aq=f&amp;oq=" target="_blank">в гугле</a>. Но для нашего случая ничего сверх-умного не нужно. А именно:</p>
<pre><code class="php">
preg_match('|(.*)&lt;title&gt;(.*)&lt;/title&gt;|is', $html, $data);
print_r ($data);
</code></pre>
<p>Подробнее об это функции можно почитать <a href="http://dimoning.ru/r.php?url=http://ru2.php.net/manual/ru/function.preg-match.php" target="_blank">тут</a>.</p>
<p><strong>4. Запись вытащенного значения.</strong></p>
<p>Тут вообще все просто и конкретная реализация зависит от Ваших потребностей. Например, если нужно записать данные в блог на ВП, записывайте их в таблицу wp_posts. В нашем примере вытащенные данные хранятся в $data[1], поэтому запись может выглядеть так:</p>
<pre><code class="php">
mysql_query ("INSERT INTO content VALUES (0, '".$data[1]."');")
    or die(mysql_error());
</code></pre>
<p>И помните &#8211; авторские права нужно соблюдать, поэтому граббер написан в образовательных целях для автоматизации рутинной работы (например, вытащить ссылки на блоги из ЯндексБлогов).</p>
<p>Постовой: <a href="http://www.bigadget.ru/">Новые гаджеты</a></p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/kak-napisat-grabber.html/feed</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>Как создать СДЛ самому, часть 1: о шаблонах, встроенных дизайнах и шаблонизаторах</title>
		<link>http://dimoning.ru/kak-sozdat-sdl-samomu-chast-1-o-shablonah-vstroennyih-dizaynah-i-shablonizatorah.html</link>
		<comments>http://dimoning.ru/kak-sozdat-sdl-samomu-chast-1-o-shablonah-vstroennyih-dizaynah-i-shablonizatorah.html#comments</comments>
		<pubDate>Sun, 23 Nov 2008 21:41:10 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[Движки, CMS]]></category>
		<category><![CDATA[Общее]]></category>
		<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=712</guid>
		<description><![CDATA[Я решил опять перейти на программистскую тематику, но писать для &#171;обычных людей&#187;. Не секрет, что для создания хорошего сайта (в основном СДЛ, но не обязательно), приходится писать к нему CMS на заказ. В основном это не дешевле 400$, поэтому для начинающего манимейкера невозможно.
Будет несколько частей, сколько &#8211; я не знаю. Если что-то хочется узнать или [...]]]></description>
			<content:encoded><![CDATA[<p>Я решил опять перейти на программистскую тематику, но писать для &laquo;обычных людей&raquo;. Не секрет, что для создания хорошего сайта (в основном СДЛ, но не обязательно), приходится писать к нему CMS на заказ. В основном это не дешевле 400$, поэтому для начинающего манимейкера невозможно.</p>
<p>Будет несколько частей, сколько &#8211; я не знаю. Если что-то хочется узнать или спросить &#8211; всегда пожалуйста.</p>
<p>Если до сих пор непонятно, что я буду вещать, поясняю: как &laquo;по кубикам&raquo; написать CMS портального типа, не зная программирования. Как сделать голосование, блоги пользователей, регистрацию пользователей, каталоги и прочее, прочее, прочее. Похоже, можно делать неограниченное количество таких постов.</p>
<p><span id="more-712"></span></p>
<p>Это первая часть, поэтому несколько моментов: я учту, что заботиться о безопасности скриптов нужно сразу, по совету умных людей (простите, уже запамятовал, с кем спорили), писать будем на PHP, и все-таки необходимо знать хотя бы основы программирования на PHP. Если непонятно, что читать, см. один из старых постов: <a href="http://dimoning.ru/vyigodno-li-byit-programmistom.html" target="_blank">Как стать программистом</a>.</p>
<p>На серию статей планы наполеоновские:</p>
<p>1. Шаблоны. (этот урок)<br />
2. Движок для вывода статических страниц.<br />
3. Прикрутить Smarty.<br />
4. Авторизацию пользователей.<br />
5. Опросы.</p>
<p>Осталось писать регулярно. Итак, к уроку.</p>
<p><strong>Шаблоны или встроенный дизайн?</strong></p>
<p>Когда Вы пишите сайт, всегда есть внешняя сторона происходящего &#8211; то, что видит пользователь, дизайн и оформление. Предположим, что дизайнер нарисовал картинку, верстальщик разрезал ее и отдал нам HTML-страницу. А нам нужно встроить ее в движок и выводить информацию (из базы данных или еще откуда-то) согласно этому оформлению.</p>
<p>Если отбросить детали, то есть 2 способа обработки дизайна (форматирования вывода данных). Первый &#8211; это встроенный в движок дизайн. Второй &#8211; шаблонизатор (и шаблон дизайна).</p>
<p><strong><em>Встроенный дизайн.</em></strong></p>
<p>Этот способ проще реализовать, но сложнее эксплуатировать. Больше того, если позже этим сайтом будет заниматься человек, не знакомый с программированием, такой способ может доставить ему некоторые сложности, когда он захочет что-то поменять. А перетянуть весь дизайн может быть сложно даже программисту, ранее не знакомому с этим движком.</p>
<p>Итак, к сути. Например, у нас есть какое-то оформление а-ля &lt;div id=&#8217;aaa&#8217;&gt;&lt;/div&gt;, а между &lt;div&gt; нам нужно вывести какую-то информацию. Тогда в этом случае, мы просто выводим ее с помощью операторов PHP прямо в файле сценария *.php: &lt;div id=&#8217;aaa&#8217;&gt;&lt;?php echo $a; ?&gt;&lt;/a&gt;</p>
<p>Получается, что если у нас 30 разных файлов, то в них по кускам везде появляется оформление (HTML). И поменять его или найти именно тот сценарий, куда закралась ошибка оформления становится сложно.</p>
<p><strong>Шаблонный дизайн.</strong></p>
<p>При этом весь дизайн оформляется в виде отдельного файла с HTML-разметкой, куда вставляются метки для вывода информации. Часто файл с дизайном имеет расширение *.tpl, и его содержимое похоже на такое: &lt;div id=&#8217;aaa&#8217;&gt;{title}&lt;/div&gt;. Потом PHP-сценарий должен обработать этот файл, считать его содержимое, заменить &laquo;метки&raquo; (для примера здесь {title}) на реальную информацию и вывести все это пользователю.</p>
<p>Все распространяемые CMS поддерживают шаблонный дизайн, что обеспечивает возможность создавать для них темы оформления. Тогда их нужно просто залить в отдельный каталог и включить через админку. Как видите &#8211; и править их легче, все в одном файле, наглядно и понятно.</p>
<p><strong>Шаблонизаторы.</strong></p>
<p>Обычно так называются скрипты (модули движка), обрабатывающие эти самые шаблоны из предыдущего пункта. Очень хороший пример такого шаблона &#8211; <a href="http://dimoning.ru/r.php?url=http://www.smarty.net/manual/ru/" target="_blank">Smarty</a>, очень рекомендую к рассмотрению и изучению. Хороший пример собственно написанного шаблонизатора &#8211; это DLE.</p>
<p>Часто программисты не пишут свой шаблонизатор, а встраивают в свой движок Smarty. Я думаю, что это лучший выход, т.к.:</p>
<p>1) Уже все написано, не тратится время на создание шаблонизатора;<br />
2) Он работает быстро. Если новичек попробует написать свой шаблонизатор, он, возможно, будет работать медленнее;<br />
3) Он бесплатно распространяется и бить Вас за это не будут;<br />
4) Очень важно, что другой разработчик сразу будет знать как работать с ним.</p>
<p>Конечно, этот пост кажется совсем не для новичков :) Но это первое, на что мы наткнемся на &laquo;практических занятиях&raquo;, т.к. оформление (вывод) информации в браузер есть даже в самом минималистическом скрипте.</p>
<p>В следующий раз попробуем написать костяк движка, чтобы он мог выводить статические страницы, шаблон будет встроенный (см. 1 пункт).</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/kak-sozdat-sdl-samomu-chast-1-o-shablonah-vstroennyih-dizaynah-i-shablonizatorah.html/feed</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Создаем счетчик-картинку, показывающий беки на сайт.</title>
		<link>http://dimoning.ru/back-counter-1.html</link>
		<comments>http://dimoning.ru/back-counter-1.html#comments</comments>
		<pubDate>Thu, 09 Oct 2008 10:03:38 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[Общее]]></category>
		<category><![CDATA[Общие советы]]></category>
		<category><![CDATA[на PHP]]></category>
		<category><![CDATA[на WordPress]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=600</guid>
		<description><![CDATA[Вот думал я думал и придумал сделать счетчик, который показывает не посещения, а количество беков на сайт. Вообще, показывать он может хоть попугаев, просто ничего оригинальнее я не придумал. Но после прочтения поста Вы будете знать: как сграбить инфу с другого сайта (нам тут нужно же узнавать где-то количество беков) и как сгенерировать красивый счетчик. [...]]]></description>
			<content:encoded><![CDATA[<p>Вот думал я думал и придумал сделать счетчик, который показывает не посещения, а количество беков на сайт. Вообще, показывать он может хоть попугаев, просто ничего оригинальнее я не придумал. Но после прочтения поста Вы будете знать: как сграбить инфу с другого сайта (нам тут нужно же узнавать где-то количество беков) и как сгенерировать красивый счетчик. И, вероятно, я разделю этот пост на 2. (вторая часть <a href="http://dimoning.ru/back-counter-2.html" target="_blank">тут</a>)</p>
<p>Начнем со второй части, т.к. она интереснее. Будем делать картинку-счетчик!</p>
<p><span id="more-600"></span></p>
<p>Что нам нужно? Вывести счетчик с нужными нам цифрами. Для этого мы заранее сделаем заготовку-фон, где нарисуем сам счетчик. А цифры будем выводить &laquo;на лету&raquo; с помощью PHP и библиотеки GD. Именно таким образом работают все счетчики &#8211; и LiveInternet и прочие. Различие может быть разве в том, что для вывода цифр может использоваться JavaScript или другой язык.</p>
<p>Итак, готовим картинку. Не забудьте оставить свободное место для цифры! У меня руки из попы в плане рисования и дизайна, поэтому у меня вышло так:</p>
<p><img class="aligncenter size-full wp-image-599" title="counter" src="http://dimoning.ru/wp-content/uploads/2008/10/counter.jpg" alt="" width="88" height="33" /></p>
<p>В середине оставлено место для динамической подстановки цифры (количества ссылок в данном случае).</p>
<p>Ну а теперь нужно сделать скрипт, который обрабатывал бы это изображение и записывал бы на нужное место нужную цифру. Скрипт на удивления короткий и простой (спасибо GD!):</p>
<pre><code class="php">
$x = 40;
$y = 8;
$number = 10;

$image = @ImageCreateFromJPEG("counter.jpg");
header ("Content-type: image/png");
$txt_color = imagecolorallocate ($image, 255, 255, 255);
imagestring($image, 2, $x, $y, $number, $txt_color);
imagepng ($image);
imagedestroy ($image);
</code></pre>
<p>Три первых переменные (я специально вынес их как переменные) это: $x &#8211; расположение текста по горизонтали (координата), $y &#8211; расположение текста по вертикали (координата), $number &#8211; это текст, который нужно вывести, а точнее &#8211; количество ссылок, поэтому оно здесь числом.</p>
<p>Логика скрипта тоже очень простая. Сначала мы открываем изображение (оно у меня названо counter.jpg) с помощью функции ImageCreateFromJPEG и затыкаем этой функции рот с помощью кляпа (не даем вывести возможное сообщение об ошибке или варнинге с помощью &laquo;@&raquo;). Потом отправляем браузеру заголовок с тем, что мы сейчас будем выводить png-изображение. Теперь обозначаем для этого изображения белый цвет и записываем его в $txt_color. С помощью imagestring выводим нужный нам текст в нужное нам изображение в нужные нам координаты нужным нам цветом. И с помощью imagepng и imagedestroy выводим изображение и уничтожаем его в памяти, дабы место не жрало.</p>
<p>Если посметить скрипт и изображение в один каталог и открыть скрипт через браузер Вы увидите изображение! 90% работы сделано.</p>
<p>Теперь чуть-чуть о вызове этого счетчика из кода страницы. Создаем какой-нибудь файл, например index.php и пишем туда вот это:</p>
<pre><code class="html">
&lt;img src="./counter.php"&gt;
</code></pre>
<p>Вот и все! Изображение выводится. Единственное, что еще хорошо было бы сделать, это проверить, а подключена ли у нас GD-библиотека :shock: Для этого в том же index.php (не в скрипте, рисующим счетчик, т.к. там Вы сообщения об ошибке не увидите &#8211; просто изображение не сформируется) пишем тоже не хитрую инструкцию, проверяющую доступна ли какая-нибудь функция библиотеки GD:</p>
<pre><code class="php">
if (!function_exists('imagetypes')) die ('Не найдена GD!');
</code></pre>
<p>До новых встреч, ребята :)</p>
<p><strong>Постовой:</strong><br />
<a href="http://www.goa-info.ru/">туры в ГОА</a></p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/back-counter-1.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Изображение с водяными знаками &#8211; как они это делают?</title>
		<link>http://dimoning.ru/vodyanoi-znak-gd2-php.html</link>
		<comments>http://dimoning.ru/vodyanoi-znak-gd2-php.html#comments</comments>
		<pubDate>Sun, 31 Aug 2008 23:02:42 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[на PHP]]></category>
		<category><![CDATA[Кор]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=443</guid>
		<description><![CDATA[Все СЕОшники знают, что накладывать водяные знаки на картинки &#8211; это хорошо. Пользователи часто передают картинки &#171;из рук в руки&#187;, например с целью &#171;Посмотри, какой ржач!&#187; или &#171;Вот как круто выглядит процессор, который я купил!&#187;.
Где выгода нам? Если на картинке будет &#171;водяной знак&#187;&#8230; А, да &#8211; водяным знаком в Веб называется просто другое изображение, наложенное [...]]]></description>
			<content:encoded><![CDATA[<p>Все СЕОшники знают, что накладывать водяные знаки на картинки &#8211; это хорошо. Пользователи часто передают картинки &laquo;из рук в руки&raquo;, например с целью &laquo;Посмотри, какой ржач!&raquo; или &laquo;Вот как круто выглядит процессор, который я купил!&raquo;.</p>
<p>Где выгода нам? Если на картинке будет &laquo;водяной знак&raquo;&#8230; А, да &#8211; водяным знаком в Веб называется просто другое изображение, наложенное на данное изображение. Обычно водяным знаком является просто строка с адресом сайта, откуда это изображение было взято. В общем, мне уже не надо продолжать предложение &laquo;Если на картинке будет водяной знак, а картинка понравится пользователю, то он обязательно заглянет на Ваш сайт&raquo;?</p>
<p>Примером водяного знака может служить <a href="http://pics.rbc.ru/img/cnews/2006/06/19/mediacenter5.jpg" target="_blank">это изображение</a> (обратите внимание на правый нижний угол).</p>
<p>Этот процесс можно автоматизировать, прикрутив автоматическое наложение водяного знака на изображение прямо во время загрузки. И я покажу как.</p>
<p><span id="more-443"></span></p>
<p>Для работы, как обычно, используется PHP, т.к. Ваш сайт наверняка нписан на нем. А для наложения графики будет использовать расширение PHP для работы с графикой. А именно &#8211; библиотека GD2. Включить ее в Windows можно, раскомментировав соответствующий модуль. В линуксе &#8211; перекомпилировав PHP с соответствующими флагами.</p>
<p>Я не буду вдаваться в саму библиотеку. Я приведу сразу код, а потом объясню, что он делает.</p>
<pre><code class="php">
$znak_hw = getimagesize("znak.png");
$foto_hw = getimagesize("foto.jpg");

$znak = imagecreatefrompng  ("znak.png");
$foto = imagecreatefromjpeg ("foto.jpg");

imagecopy ($foto,
$znak,
$foto_hw[0] - $znak_hw[0],
$foto_hw[1] - $znak_hw[1],
0,
0,
$znak_hw[0],
$znak_hw[1]);

imagejpeg ($foto, "done.jpg", "100");

imagedestroy ($znak);
imagedestroy ($foto);
</code></pre>
<p>Библиотека GD2 очень сильно облегчает жизнь программисту, когда приходится работать с графикой. Сейчас поймете почему.</p>
<p>В каталоге со скриптом должны лежать еще 2 файла &#8211; foto.jpg (это изображение, НА которое нужно наложить водяной знак) и znak.png (это сам знак). Если Вы хотите, чтобы накладывалась, например, только надпись (без фона), то сделайте фон (все, что не является самим знаком) прозрачным (именно поэтому был выбран формат png).</p>
<p>Итак. Сначала мы получаем размеры наших изображений. Даже файл открывать не надо! Для этого подходит функция <a href="http://ru2.php.net/manual/ru/function.getimagesize.php" target="_blank">getimagesize</a>, принимает на вход имя файла. Полученные размеры записываются в массив, где в нулевой ячейке будет ширина, а в первой &#8211; высота (в пискелах, разумеется).</p>
<p>После получения размеров, нужно создать в памяти интерпретатора сами изображения, чтобы было с чем работать (потом обработанное изображение записывается в файл). Для этого здесь нам нужны две функции <a href="http://ru2.php.net/manual/ru/function.imagecreatefrompng.php" target="_blank">imagecreatefrompng</a> (читает формат png) и <a href="http://ru2.php.net/manual/ru/function.imagecreatefromjpeg.php" target="_blank">imagecreatefromjpeg</a> (читает формат jpg, соответственно). Возвращает дескриптор изображение (&laquo;ресурс&raquo;, как принято называть его в PHP).</p>
<p>После того, как мы загрузили изображение в память, их можно начать обрабатывать. Здесь в качестве обработки выступает единственная операция &#8211; копирование одного изображение на другое (водяной знак копируется на фото). Для копирования мы используем функцию imagecopy, которая принимает следующие параметры: исходное изображение, копируемое на него изображение, координаты расположения копируемого изображения (два штука), и область самого копируемого изображения (четыре штука).</p>
<p>Координаты расположения копируемого изображение &#8211; это координаты левого верхнего угла копируемого изображения на фото. Здесь мы от размеров фотки отнимаем размеры знака и получется, что изображение копируется аккуратно в угол.</p>
<p>Размеры копируемого изображения остаются оригинальными &#8211; с левого верхнего его угла по правый нижний.</p>
<p>Следующим шагом нам нужно создать получившееся изображение. Мы создаем его с помощью функции <a href="http://ru2.php.net/manual/ru/function.imagejpeg.php" target="_blank">imagejpeg</a>, которая, соответственно, создает изображение в формате jpg.</p>
<p>Удаляем дескрипторы, чтобы не засирать память с помощью функций <a href="http://ru2.php.net/manual/ru/function.imagedestroy.php" target="_blank">imagedestroy</a>. Они не удаляют сам файл, не волнуйтесь.</p>
<p>Все, наше изображение готово. Интегрировать такую обработку очень просто. Нужно на этапе загрузки файла, обработать временное изображение (filename_tmp) и после этого скопировать его в уже каталог назначения.</p>
<p>И еще одна подсказка. Чтобы каждый раз не смотреть в файл, &laquo;что там у нас получилось&raquo;, можно выводить изображение прямо в браузер. Так гораздо быстрее для отладки. Для вывода изображения в браузер закомментируйте строку</p>
<pre><code class="php">imagejpeg ($foto, "done.jpg", "100"); </code></pre>
<p>и напишите вот такой код вместо нее:</p>
<pre><code class="php">header ('Content-Type: image/gif');
imagegif ($foto);
</code></pre>
<p>Конечно, перед header() никакого вывода в браузер быть не должно, иначе заголовок не отправится.</p>
<p>Удачи! :)</p>
<p>Спонсор поста: <a href="http://hoster.od.ua/">недорогой хостинг</a></p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/vodyanoi-znak-gd2-php.html/feed</wfw:commentRss>
		<slash:comments>43</slash:comments>
		</item>
		<item>
		<title>Как написать свой движок блога, часть 2. Авторизация в админке.</title>
		<link>http://dimoning.ru/kak-napisat-svoy-dvizhok-bloga-2.html</link>
		<comments>http://dimoning.ru/kak-napisat-svoy-dvizhok-bloga-2.html#comments</comments>
		<pubDate>Fri, 22 Aug 2008 17:39:18 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[Движки, CMS]]></category>
		<category><![CDATA[Общие советы]]></category>
		<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=387</guid>
		<description><![CDATA[Спонсор поста: грузчики
Пришло время второй части саги о создании собственного движка блога.
Первая часть здесь. Но перед этим пара слов на отвлеченную тему.
В предыдущем посте я просил помочь моей супер-черепахе на домик для нее, и уже через несколько часов откликнулся замечательный человек &#8211; Илья, пожертвовал в фонд 70 рублей. Он по &#171;призванию&#187; СЕОшник и недавно открыл [...]]]></description>
			<content:encoded><![CDATA[<p>Спонсор поста: <a href="http://www.vash-gruzchik.ru">грузчики</a></p>
<p>Пришло время второй части саги о создании собственного движка блога.</p>
<p><a href="http://dimoning.ru/kak-napisat-svoy-dvizhok-bloga-1.html" target="_blank">Первая часть здесь</a>. Но перед этим пара слов на отвлеченную тему.</p>
<blockquote><p>В предыдущем посте я просил <a href="http://dimoning.ru/plan-zahvata-mira-2-bosonogiy-pravitel.html" target="_blank">помочь моей супер-черепахе на домик для нее</a>, и уже через несколько часов откликнулся замечательный человек &#8211; Илья, пожертвовал в фонд 70 рублей. Он по &laquo;призванию&raquo; СЕОшник и недавно открыл свой блог, который обещает быть очень неплохим: <a href="http://seoinsoul.ru/" target="_blank">SEO in Soul.ru, Душевный Блог о SEO и Заработке</a>.</p></blockquote>
<p><strong>Теперь о создании своего движка блога.</strong> Я реализовал следующее: создание/редактирование/удаление постов, создание/редактирование/удаление категорий, написание комментариев и их редактирование через систему администрирования. Скачать то, что получилось можно по ссылке в конце поста (там пока что архив без редактирования комментариев из админки). Когда дойдем до безопасности, я залью этот движок на тестовый поддомен и можно будет посмотреть, что вышло. И опять эта статья обещает быть очень длинной. Боюсь, что придется ее разрезать еще на три части &#8211; авторизация в админке (эта статья), действия с постами и категориями, действия с комментариями и комментирование. А потом еще две части &#8211; вывод всего этого на сайт и безопасность движка. Пора писать книгу. (Если кого-то не устраивает такая &laquo;санта барбара&raquo; &#8211; пишите, буду делать статьи длиннее)</p>
<p><span id="more-387"></span></p>
<p>Для начала замечу, что все <em>GET-параметры передаются через .htaccess</em> и &laquo;откуда они берутся&raquo; вопрос не принимается :) Это я <a href="http://dimoning.ru/kak-napisat-svoy-dvizhok-bloga-1.html" target="_blank">объяснил в первой части</a>.</p>
<p><strong>Создание системы администрирования. </strong></p>
<p>Я вообще рекомендую всегда разрабатывать движок с админки, т.к. в ней частично или полностью реализован вывод данных, то есть фактически &#8211; пользовательская часть. Тогда создание пользовательской части пойдет быстрее, на мой взгляд. В общем, с админки и начнем.</p>
<p>Располагается она по адресу /vrotmnenogi-admin/, как заявлено в ТЗ (см. <a href="http://dimoning.ru/kak-napisat-svoy-dvizhok-bloga-1.html" target="_blank">первую часть</a>). Я довольно быстро раскаялся в своей дурацкой шутке, т.к. писать везде такой длинный адрес не особенно удобно :). Но от ТЗ мы не будем отступать принципиально, это полезный навык. Простите мне такой бред, я честно не хотел :lol:</p>
<p>Конечно, для начала нужно сделать в админке систему входа, чтобы кто попало не мог редактировать содержимое блога. Авторизация будет вполне обычная &#8211; через логин и пароль. Их md5-хеш будет сохраняться в Cookie и по нему пользователь будет проверяться каждый раз, когда что-то делает в админке.</p>
<blockquote><p>MD5 &#8211; в данном случае применяется как однонаправленный алгоритм шифрования строк произвольной длины и получения 128-битного хеша. Другими словами, если зашифровать любое слово этим алгоритмом, то обратно расшифровать его уже нельзя. Понятно, что для проверки нужно зашифровать введенный пользователем логин/пароль и сравнить его с уже имеющимся хешем. Если они совпадают, то пользователь ввел правильный логин/пароль.</p></blockquote>
<p>Храниться имя и пароль будут прямо в скрипте в виде переменных (файл /vrotmnenogi-admin/index.php, самый верх). Для еще большей путаницы мы будем добавлять в эту связку секретный ключ (произвольный набор символов), чтобы хакер совсем сломал голову, расшифровывая данный хеш.</p>
<p>Итак, как мы будем проверять вход? Для этого создан файл logintest.php, лежащий прямо в корне админки. Первой строкой в этом файле мы смотрим, не пытается ли пользователь залогиниться? Логин передается в переменной $_POST['login'] и если она не пуста, значит &#8211; пытается. Соответственно первым ветвлением IF мы проверяем, что он нам такого прислал и сравниваем с хешем строк пароля, логина и секретного ключа:</p>
<pre><code class="php">
if ($_POST['login']){
	if ($_POST['login'] == $admin_login &amp;&amp;
		$_POST['password'] == $admin_password){
		setcookie ("admin_login", $protection_combo,
                                 time() + 60*60*24*7);
		header ("location: /vrotmnenogi-admin/");
	}
}
</code></pre>
<p>Если проверка пройдена, то мы устанавливаем куки, в которую и записан этот хеш. Куки ставится на неделю и работает только для каталога /vrotmnenogi-admin/ нашего движка. И потом отправляем заголовок, который переадресовывает нас на главную страницу. То есть &#8211; для пользователя не видно, что выполняется какой-то скрипт, все происходит &laquo;мгновенно&raquo;.</p>
<p>Следующий блок в этом файле &#8211; это как раз вывод формы ввода логина и пароля. То есть, если не передано поле $_POST['login'] и данные в куки не совпадают с хешем (попытка взлома или просто нет куки &#8211; не залогинен), то выводится форма входа:</p>
<pre><code class="php">
// Проверка, введен ли пароль админа
if ($_COOKIE['admin_login'] != $protection_combo){
	?&gt;
	&lt;form action="./index.php" method="post"&gt;
		Логин: &lt;input name="login"&gt;&lt;br&gt;
		Пароль: &lt;input name="password" type="password"&gt;&lt;br&gt;
		&lt;input type="submit" value="Зайти на огонек"&gt;
	&lt;/form&gt;
	&lt;?php
	exit;
}
</code></pre>
<p>Кстати, обратите, пожалуйста внимание на то, что после вывода формы обязательно должна быть команда exit. Иначе после формы выведется сама админка. После нажатия кнопки &laquo;Войти&raquo; все данные как раз и проверяются блоком кода, описанным чуть выше.</p>
<p>Теперь выход. Тут все очень просто. В файле index.php я создал кнопку, при нажатии на которую выполняется скрипт logout.php. Кнопку назвал незатейливо &#8211; &laquo;Выйти&raquo; :)</p>
<pre><code class="html">&lt;form action="./logout.php" method="post"&gt;
	&lt;input type="submit" value="Выйти"&gt;
&lt;/form&gt;
</code></pre>
<p>Никакого криминала :) Ну и сам скрипт выхода. Он просто убивает куки с хешем логина, пароля и секретного ключа, из-за чего пользователь не пройдет проверку в файле logintest.php:</p>
<pre><code class="php">&lt;?php
setcookie ("admin_login", "");
header ("location: /vrotmnenogi-admin/");
?&gt;</code></pre>
<p>Убиваем куки (передав ей пустое значение) и отправляем пользователя на главную страницу. Вот так.</p>
<p>С админкой на этом все. Следующая статья в этой серии будет, как я и сказал, о постах и о категориях. Удачи!</p>
<p><strong><a href="http://dimoning.ru/wp-content/uploads/2008/08/dblog.rar" target="_blank">Скачать архив с движком </a><a href="http://dimoning.ru/wp-content/uploads/2008/08/dblog.rar">dblog</a>.</strong> Используйте как угодно, только название dblog остается за мной ;) В архиве, кстати, функционала больше, чем я здесь описал.</p>
<p>__________________________</p>
<p>Если никто не против, чуть-чуть личного. Заметил, что писать в блог для меня стало чем-то нужным. То есть меня мучает ощущение &laquo;надо бы написать в блог&raquo;. Приятное ощущение, что-то вроде тяги к наркотикам для наркоманов :lol: При этом, когда пишешь в блог, это ощущение на день-два отпускает. Мне страшно :shock:</p>
<p>Кстати, я вроде бы пошел на поправку (болел тут несколько дней). Моя девушка подарила мне забавную картинку :)</p>
<p><a href="http://dimoning.ru/wp-content/uploads/2008/08/1195678725_turkey.jpg"><img class="aligncenter size-medium wp-image-389" title="1195678725_turkey" src="http://dimoning.ru/wp-content/uploads/2008/08/1195678725_turkey-278x300.jpg" alt="" width="278" height="300" /></a></p>
<p>Спасибо ей большое, очень классно получилось : )))</p>
<p>А еще по поводу болезней. Трехчасовой рабочий день пишет в своем блоге <a href="http://3hours.biz/drugoy-vzglyad-na-len/" target="_blank">другой взгляд на лень</a> (медицинский, так сказать). После чего (по совету ТРД?) Кишиневский бомж проверяется у врача и у него <a href="http://homelessinchisinau.blogspot.com/2008/08/blog-post.html" target="_blank">находят опухоль щитовидной железы</a>.</p>
<p><strong>Дорогой Кишиневский бомж</strong>, во-первых: мы все с тобой, держись! А во-вторых, я спросил у знающих людей, говорят, что эти опухоли доброкачественные и с ними живет чуть ли не половина жителей Санкт-Петербурга и даже не знает об этом. Все будет хорошо ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/kak-napisat-svoy-dvizhok-bloga-2.html/feed</wfw:commentRss>
		<slash:comments>38</slash:comments>
		</item>
		<item>
		<title>Как написать свой движок блога, часть 1.</title>
		<link>http://dimoning.ru/kak-napisat-svoy-dvizhok-bloga-1.html</link>
		<comments>http://dimoning.ru/kak-napisat-svoy-dvizhok-bloga-1.html#comments</comments>
		<pubDate>Thu, 14 Aug 2008 08:32:20 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[Движки, CMS]]></category>
		<category><![CDATA[Общие советы]]></category>
		<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=353</guid>
		<description><![CDATA[Спонсор поста: деревообрабатывающая промышленность, продажа леса
Вступление.
Собственный движок блога обладает многими преимуществами. В нем можно поменять вообще все, до мелочей и уйдет на это в 10 раз меньше времени, чем ковыряться в чужих движках, таких как WordPress или DLE (DLE особенно страшен в этом плане на мой взгляд). Для него легко поставить собственный дизайн. К нему [...]]]></description>
			<content:encoded><![CDATA[<p>Спонсор поста: <a href="http://www.woodsale.ru" target="_blank">деревообрабатывающая промышленность</a>, <a href="http://www.woodsale.ru/classifieds/" target="_blank">продажа леса</a></p>
<p><strong>Вступление.</strong></p>
<p>Собственный движок блога обладает многими преимуществами. В нем можно поменять вообще все, до мелочей и уйдет на это в 10 раз меньше времени, чем ковыряться в чужих движках, таких как WordPress или DLE (DLE особенно страшен в этом плане на мой взгляд). Для него легко поставить собственный дизайн. К нему легко прикрутить собственные другие наработки, например, портал, каталог статей и прочее.</p>
<p>Большим плюсом номер два я считаю невозможность взлома собственного движка. Ведь для взлома уникального, нигде больше не установленного движка хакеру придется поломать голову. А вот для стандартных движков обычно делают даже так называемые эксплойты &#8211; скрипт, запустив который, даже безмозглый 12летний идиот может получить пароли от админки Вашего блога.</p>
<p>Да, это палка о двух концах &#8211; если плохо написать движок с точки зрения безопасности, ломаться он будет довольно легко. Но я лично не собираюсь писать его плохо ;) А Вы?</p>
<p>Еще плюсы? Например, скорость работы. Тот же огромный и &laquo;тяжелый&raquo; WordPress будет работать в разы медленнее, чем заточенный под конкретные задачи собственный движок.</p>
<p>Я расскажу, как написать свой движок за пару часов. А если копировать код у меня из статьи &#8211; за 15 минут. А если сразу скачать исходник &#8211; за 30 секунд :)</p>
<p><span id="more-353"></span></p>
<p>(тут поясню: у меня блог на стандартном движке, т.к. я его веду уже больше полугода и мне не хочется возиться с переносом статей на собственный движок; жаль, что я не начал вести блог на своем движке с самого начала)</p>
<p><strong>Недостатки есть?</strong></p>
<p>Есть, не без этого. Главным недостатком своего движка и огромным плюсом для стандартных движков я считаю плагины. То есть для собственного движка их просто нет и быть не может, пока автор движка сам их не напишет. Например, в WordPress можно за 1 минуту установить плагин для вывода последних комментариев, вывода смайликов, голосования (и вообще чего угодно), а в своем блоге придется писать это все самому. И если вывод последних комментариев и смайликов &#8211; задача не сложная, то, например, с голосованием уже посложнее.</p>
<p><strong>Зачем Вам все это?</strong></p>
<p>В любом случае, даже если Вы выбираете стандартный движок, я все равно рекомендую прочитать статью &#8211; особенно начинающим программистам. Эта статья фактически описание создания несложной CMS, которую можно превратить из блога во что угодно ;)</p>
<p>И еще момент. После этого небольшого цикла статей я напишу, как сделать генератор сателлитов! И по плану &#8211; там как раз пригодится этот собственный движок ;) Запахло деньгами?</p>
<p><strong>Составляем ТЗ.</strong></p>
<p>(ТЗ &#8211; Техническое Задание, документ, по которому программист пишет программу, скрипт, сайт и т.п.)</p>
<p>Даже в таком несложном деле лучше составить небольшое ТЗ и не отходить от него в процессе разработки. Мы просто опишем, что хотим видеть в движке, а потом сделаем ровно так, как написали. Я считаю, что это полезная практика &#8211; иначе можно &laquo;расплыться&raquo; (захотеть сделать и то и се и пятое и десятое, в итоге не сделать ничего или сделать частично и плохо).</p>
<p>&laquo;Нужны возможности: 2* добавлять категории, редактировать их названия, вывод категорий по алфавиту, вложенность не нужна. Добавлять, редактировать или удалять посты. В посте есть заголовок и основной текст. Визуальный редактор не нужен, разрешить HTML-теги. 3* Возможность комментировать пост, вводя имя, почту, сайт и комментарий. Регистрация пользователей не нужна. Все адреса в виде ЧПУ (человеку понятный URL, а-ля dimoning.ru/hello.html). Категории открываются по адресам /category/catname/, где catname &#8211; имя категории. Посты открываются по адресам /postname.html, где postname &#8211; адес поста. Эти адреса тоже можно редактировать. *4 Прикрутить RSS последней версии протокола. Весь блог в кодировке UTF-8. Все изменения администратор вводит через админку по адресу /vrotmnenogi-admin/. Добавить постраничный вывод постов.&raquo;</p>
<p>Вот такое тех-задание. Сделаем четко по нему ;)</p>
<p>Я решил разделить создание собственного движка блога на четыре части &#8211; первая &#8211; это проектирование и еще три отмечены звездочками в ТЗ [сначала хотел 3 части, но эта статья уже вышла довольно большой, а для понимания читать большую статью, я думаю, тяжеловато]. У меня еще нет готового движка (на момент написания этих строк), поэтому исходник каждый раз будет все более дополняться.</p>
<p><strong>Начнем с начала.</strong></p>
<p>В начале работы я обычно прикидываю, какие мне нужны таблицы в базе данных и как их будет использовать движок. Например, здесь. Я перечислю поля и тип данных в них записываемый, а также объясню &#8211; для чего то или иное поле. Для простоты мы будем использовать только int и text.</p>
<p><em>Категории:</em><br />
id <em>(int auto increment)</em> | url <em>(text)</em> | title <em>(text)</em></p>
<p>id &#8211; уникальный, автоматически увеличивающийся при добавлении записи, идентификатор категории<br />
url &#8211; адрес категории, который будет подставляться /category/сюда/<br />
title &#8211; название категории, которое будет выводиться в браузер</p>
<p><em>Посты:</em><br />
id <em>(int auto increment)</em> | url <em>(text)</em> | title <em>(text)</em> | post <em>(text)</em> | dt <em>(datetime)</em></p>
<p>id &#8211; уникальный, автоматически увеличивающийся при добавлении записи, идентификатор поста<br />
url &#8211; адрес поста, который будет подставляться /сюда.html<br />
title &#8211; заголовок поста, выводится в браузер<br />
post &#8211; содержимое поста, выводится туда же<br />
dt &#8211; дата и время написания поста, проставляется автоматически и изменению не подлежит</p>
<p><em>Комментарии к постам:</em><br />
id <em>(int auto increment)</em> | post_id <em>(int)</em> | nick <em>(text)</em> | email <em>(text)</em> | site <em>(text)</em> | comment <em>(text)</em> | ip <em>(text)</em> | dt <em>(datetime)</em></p>
<p>В ТЗ ничего не сказано про запись IP комментатора, но я считаю, что это необходимо. Может помочь отловить злого спамера или забанить по IP. В общем, если &laquo;враг&raquo; появится, лучше знать про него как можно больше.</p>
<p>id &#8211; уникальный, автоматически увеличивающийся при добавлении записи, идентификатор комментария<br />
post_id &#8211; идентификатор поста, к которому написан комментарий<br />
nick &#8211; имя комментатора (никнейм)<br />
email &#8211; почта комментатора<br />
site &#8211; сайт комментатора<br />
comment &#8211; сам комментарий<br />
ip &#8211; IP-адрес комментатора<br />
dt &#8211; дата и время написания комментария. Так. Для протокола. :)</p>
<p>Знатоки из Что-Где-Когда, конечно, заметили бы, что IP адрес можно хранить в виде long-числа, а я храню его в виде текста. Я считаю, что так нагляднее и вообще редко храню его в виде числа. Говорят, что по использованию памяти это лучше, не знаю, я не замерял. Но знаю, что это хуже по производительности &#8211; нужно преобразовывать число в IP и обратно. Я так не делаю, в общем.</p>
<p><strong>С базой данных все. Теперь пара слов о ЧПУ.</strong></p>
<p>Из ТЗ видно, что должны быть ЧПУ (человеку понятный Url). Для этого нам нужно создать .htaccess, который мог бы разбирать адреса вида /category/name/ и /post.html и передавать в скрипт значения этих полей в виде переменных. Например, пусть имя категории передается в переменной category, а имя поста в переменной post из массива $_GET.</p>
<p>Заметьте, нужно предусмотреть и постраничный вывод! Лучше подумать об этом сразу. Я предлагаю сделать примерно так же, как сделано в WordPress. А именно, для категорий страницы показываются по адресу /category/name/page/1/, где 1 &#8211; номер страницы. А если категория не выбрана (главная страница), то адреса для вывода страниц будут иметь вид /page/1/ &#8211; прямо от корня.</p>
<p>И еще нужно предусмотреть зарезервированное имя для RSS. Я предлагаю сделать простой адрес: /rss.html, почему бы и нет?</p>
<p>Какой же .htaccess файл нам понадобится? Я бы сделал такой:</p>
<p>RewriteEngine On<br />
1 RewriteRule ^(rss).html$ rss.php [L]<br />
2 RewriteRule ^([A-Za-z0-9_]+).html$ index.php?post=$1 [L]<br />
3 RewriteRule ^(category)/([A-Za-z0-9_]+)/$ index.php?category=$2 [L]<br />
4 RewriteRule ^(category)/([A-Za-z0-9_]+)/(page)/([0-9+])/$ index.php?category=$2&amp;page=$4 [L]<br />
5 RewriteRule ^/(page)/([0-9+])/$ index.php?page=$2 [L]</p>
<p>Я пронумеровал строки. В рабочей версии нумерации, конечно, нет.</p>
<p>Строка 1. Перекидывает с rss.html на rss.php прозрачно для пользователя. В rss.php будет генерироваться сама RSS.</p>
<p>Строка 2. При открытии адреса вида /some.html передает все между слешем и .html в скрипт index.php в переменной $_GET['post'];</p>
<p>Строка 3. При открытии категорий (адрес вида /category/имя/) передает в скрипт index.php имя категории в перменной $_GET['category'];</p>
<p>Строка 4 и строка 5 &#8211; аналогичное действие, только для других видов URL.</p>
<p>Ключ L не позволяет серверу идти дальше по списку, если нужное нам совпадение с адресом найдено.</p>
<p>Между прочим, здесь есть еще один большой плюс: с помощью регулярных выражений мы задали конкретные символы, которые можно использовать в адресах. Если хакер попытается ввести в адрес не буквенно-цифровой символ, то сервер прервет запрос сразу же. То есть заботиться об этом в самом движке уже не надо.</p>
<p>На этом с &laquo;проектированием&raquo; покончено, ровно как и с первой частью. В следующей статье мы сделаем добавление категорий, их редактирование, вывод. Добавление постов, их редактирование и отображение.</p>
<p>Пока что все. Всем удачи и до связи :) <a href="http://feeds.feedburner.com/dimoning" target="_blank">Подписывайтесь на RSS</a>, а то что за дела ))) Я еще не набрал даже сотни подписчиков, жуть! ))</p>
<p>__________________________<br />
Посмеялся ))<br />
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="src" value="http://www.youtube.com/v/uQrC_C6SexI&amp;hl=en&amp;fs=1" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/uQrC_C6SexI&amp;hl=en&amp;fs=1" allowfullscreen="true"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/kak-napisat-svoy-dvizhok-bloga-1.html/feed</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>Скрипт автоматической проверки обратных ссылок.</title>
		<link>http://dimoning.ru/auto-check-backlinks.html</link>
		<comments>http://dimoning.ru/auto-check-backlinks.html#comments</comments>
		<pubDate>Tue, 05 Aug 2008 12:36:06 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[Скрипты PHP]]></category>
		<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=238</guid>
		<description><![CDATA[При поддержке: регистратор доменов &#8211; дешевая и удобная регистрация доменов.
_________________________________
Для чего может понадобиться такой скрипт? Например, Вы обменялись статьями со многими веб-мастерами &#8211; их статьи висят у Вас, Ваши &#8211; у них. Конечно, рассчитывать на то, что все они порядочные люди &#8211; опрометчиво. И приходится периодически проверять, а висит ли там моя статья с моими [...]]]></description>
			<content:encoded><![CDATA[<p>При поддержке: <a href="http://estdomain.com.ua/">регистратор доменов</a> &#8211; дешевая и удобная регистрация доменов.<br />
_________________________________</p>
<p>Для чего может понадобиться такой скрипт? Например, Вы обменялись статьями со многими веб-мастерами &#8211; их статьи висят у Вас, Ваши &#8211; у них. Конечно, рассчитывать на то, что все они порядочные люди &#8211; опрометчиво. И приходится периодически проверять, а висит ли там моя статья с моими ссылочками? Или, например, Вы оплатили рекламу в <a href="http://blogun.ru/?r=7014" target="_blank">Блогуне</a>, блоггер разместил пост, но через две недели убрал. Хотя бы забаним <span style="text-decoration: line-through;">мудака</span> обманщика!</p>
<p>Аналогично, скрипт может использоваться для проверки трекбеков, хотя создавался не совсем для этого.</p>
<p><span id="more-238"></span></p>
<p>Как всегда &#8211; в конце статьи я дам ссылку на архив со скриптом, а по ходу объяснения работы скрипта, расскажу как им пользоваться для простых пользователей, не знающих программирования. Если честно, то я буквально после этой статьи быстро сделаю сервис авто-проверки ссылок, так что, в принципе, не-программистам не обязательно забивать себе голову ерундой ;) Кроме того, сервис будет проверять также наличие nofollow и noindex, что есть круче, чем этот скрипт.</p>
<p>Внимание, вспышка справа!</p>
<pre><code class="php">
header ("Content-Type: text/html; charset=utf-8");

$sites[] = "www.millioner.org/";
$sites[] = "yandex.ru";
$sites[] = "dimoning.ru/hello.txt";
$sites[] = "www.simplecoding.org";
$sites[] = "nettakogosaita.fuck";

$check_url = "dimoning.ru";

function to_utf($str){
	if (mb_detect_encoding($str, "UTF-8, ISO-8859-1, GBK")
                               != "UTF-8"){
		return  iconv("gbk", "utf-8", $str);
	}
	else{
		return $str;
	}
}

for ($i = 0; $i &lt; count ($sites); $i++){
	$sites[$i] = str_replace ("http://", "", $sites[$i]);
	$sites[$i] = "http://".$sites[$i];
}

$check_url = str_replace ("http://", "", $check_url);
$check_url = str_replace ("/", "\/", $check_url);

$ch = curl_init();
for ($i = 0; $i &lt; count ($sites); $i++){
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_CURLOPT_TIMEOUT, 10);
	curl_setopt($ch, CURLOPT_URL, $sites[$i]);
	$page = curl_exec($ch);

	echo "&lt;b&gt;".$sites[$i].":&lt;/b&gt;&lt;br&gt;";
	preg_match("/&lt;a.*?href=.*?".$check_url.".*?&gt;(.*?)&lt;\/a&gt;/",
                     $page, $m);
	$m[1] = to_utf ($m[1]);

	if (!empty ($m[1]) &amp;&amp; !empty ($page))
            echo "Ссылка: есть, с анкором: ".$m[1]."&lt;br&gt;&lt;br&gt;";

	if (empty ($m[1]) &amp;&amp; !empty ($page))
            echo "Пусто!&lt;br&gt;&lt;br&gt;";

	if (empty ($page))
            echo "// Сайт не открылся.&lt;br&gt;&lt;br&gt;";

}

curl_close($ch);
</code></pre>
<p>Совсем небольшой скрипт, способный сэкономить несколько часов Вашего времени!</p>
<p>Для начала отмечу, что это вариант скрипта, для которого нужно неограниченное время выполнения. Для VDS и выделенных серверов это можно легко поставить, на обычном хостинге &#8211; можно попробовать написать провайдеру или написать первой строкой в скрипте set_time_limit(0);.</p>
<p>Будьте осторожны с set_time_limit &#8211; во-первых, часто такая инструкция просто не срабатывает, а во-вторых, сам Веб-сервер может иметь лимит времени отдачи документа. Другими словами, даже если сам скрипт будет работать неограниченно долго, Веб-сервер может порвать сессию и результаты работы скрипта Вы так и не увидите.</p>
<p>Есть еще вариант обхода этого ограничения &#8211; записывать в файл, какой сайт проверялся последним и при повторном запуске начинать с него. Правда здесь это не реализовано, т.к. я недавно купил выделенный сервер у <a href="http://firstvds.ru/ru/home/index.html?from=9071" target="_blank">FirstVDS</a> и настроил его так, как мне нужно ;) Всего за 150 рублей я получил гораздо больше возможностей, чем на обычном хостинге за 250! Я серьезно говорю, никто меня рекламировать фествдс не просил.</p>
<p>Теперь к скрипту. Объясняю :)</p>
<p>Сначала мы указываем кодировку страницы UTF-8, ну это понятно что. Дальше в массив $sites записываются адреса сайтов для проверки. Здесь я проверяю несколько сайтов и страниц, где ссылки на меня есть и где ссылок на меня нет. На Яндексе ссылки на <a href="http://dimoning.ru" target="_blank">мой блог</a> заведомо нет :lol:</p>
<p>В переменную $check_url записывается адрес, который нужно проверить. <strong>Внимание!</strong> Записывать туда адрес без http://, без внутренней страницы. Грубо говоря в формате ??????.?? (домен и зона). Если писать туда другие адреса &#8211; не гарантируется правильность работы скрипта. Такая реализация, потому что наличие ссылки с доменом в любом случае означает, что ссылка на Ваш сайт установлена.</p>
<p>Функция to_utf используется для преобразования строки из любой кодировки в UTF-8. Дело в том, что сам скрипт в кодировке UTF-8, но если проверяемый сайт в другой кодировке, то анкор ссылки будет выводиться неверно. Функцию я скопировал с <a href="http://php.net" target="_blank">php.net</a>.</p>
<p>Первым циклом for мы гарантируем, что в адресах проверяемых сайтов будет присутствовать http://. Это нужно для подключения к ним.</p>
<p>Две строки перед вторым for &#8211; там мы обрабатываем проверяемый домен так, чтобы он не содержал http:// и заменяем все / так, чтобы они не были спец-символами.</p>
<p>Ну и самое вкусное! Инициализируем curl (библиотека для работы с удаленными сайтами) с помощью curl_init.</p>
<p>В цикле перебираем все проверяемые URL. Установленная опция CURLOPT_RETURNTRANSFER означает, чтобы результат чтения удаленного сайта не выводился на страницу, а записывался в переменную. Опция CURLOPT_CURLOPT_TIMEOUT означает, сколько времени в секундах ждать открытия сайта (здесь &#8211; 10). Если он открыться не успеет, то мы получим пустой результат. Это важно, иначе скрипт может выполняться очень долго.</p>
<p>CURLOPT_URL означает, какой URL мы сейчас будем проверять. С помощью $page = curl_exec($ch); мы и получаем код проверяемого сайта.</p>
<p>Следующим шагом мы с помощью регулярного выражения проверяем, если ли в коде нужная нам ссылка. Отличие этого метода от <a href="http://www.simplecoding.org/zashhita-ot-spama-php-skript-dlya-proverki-trekbekov.html" target="_blank">предложенного Владимиром</a> в том, что Владимир проверяет просто наличие URL на странице, а я &#8211; именно ссылки (адреса, заключенного в &lt;a&gt;). Понятно, что отличие &#8211; очень существенное и скрипт Владимира обмануть гораздо легче, к сожалению (мой вроде бы обмануть нельзя, но зарекаться не буду).</p>
<p>С помощью адского регулярного выражения (preg_match) мы и проверяем наличие ссылки. Если Вы совсем не знакомы с регулярными выражениями в PHP, рекомендую сначала <a href="http://www.softtime.ru/bookphp/gl7_1.php" target="_blank">почитать о регулярных выражениях на SoftTime.ru</a>. Коротко, то группа символов .*? означает &laquo;сколько угодно чего угодно&raquo;. Ну и все слеши / нужно экранировать обратным слешем \, чтобы они не являлись спец-символами.</p>
<p>Результат работы попадает в массив $m; Для эксперимента его интересно вывести с помощью функции print_r ();</p>
<p>В ячейку 1 массива $m попадает как раз анкор ссылки (текст ссылки). Мы его преобразовываем к UTF-8 и выводим в браузер. А потом закрываем curl.</p>
<p>Как этим пользоваться обычным пользователям? Достаточно менять в заголовке содержимое массива $sites. Грубо говоря, просто копируйте $sites[] = &laquo;yandex.ru&raquo;; на новую строку и вместо yandex.ru подставляйте свой URL для проверки. Про $check_url я уже говорил. Загружаете скрипт на сервер &#8211; запускаете и готово.</p>
<p>Вот пример результата работы скрипта:</p>
<pre><code>
<strong>http://www.millioner.org/:</strong>
Ссылка: есть, с анкором: Блог простого программиста

<strong>http://yandex.ru:</strong>
Пусто!

<strong>http://dimoning.ru/hello.txt:</strong>
Ссылка: есть, с анкором: DimoninG.ru

<strong>http://www.simplecoding.org:</strong>
Ссылка: есть, с анкором: статью об одной из уязвимостей Sape

<strong>http://nettakogosaita.fuck:</strong>
// Сайт не открылся.
</code></pre>
<p>Скачать скрипт можно здесь: <a href="/scripts/auto-check-backlinks.rar">Скрипт автоматической проверки наличия обратных ссылок от DimoninG&#8217;а (dimoning.ru).</a>.</p>
<p>Ждите сервис через пару часов ;)</p>
<p>____________________________________<br />
<a href="http://chipp.ru">Социальное пастбище для блогера</a> &#8211; социальная сеть для блоггеров, сосредоточие вселенского зла и записей из множества блогов. Можно подписаться на нее и ничего не читать &#8211; информации будет достаточно ;) И еще радует, что автор заботится о своей сети, в отличие от других аналогичных сетей.</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/auto-check-backlinks.html/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Как прятать рекламный блок, если ссылок с Сапы нет.</title>
		<link>http://dimoning.ru/esli-sape-ssyilok-net.html</link>
		<comments>http://dimoning.ru/esli-sape-ssyilok-net.html#comments</comments>
		<pubDate>Sat, 02 Aug 2008 10:43:37 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[Sape.ru]]></category>
		<category><![CDATA[на PHP]]></category>
		<category><![CDATA[на WordPress]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=211</guid>
		<description><![CDATA[Я расскажу, как преобразовать код сапы таким образом, чтобы рекламный блок на Вашем сайте вообще не показывался, если ссылок нет. Если непонятно, что я имею в виду &#8211; обратите внимание на этот блог. В сайдбаре в левой половине в самом низу на главной странице есть блок &#171;реклама&#187;, где размещаются ссылки. На других страницах блока нет. [...]]]></description>
			<content:encoded><![CDATA[<p>Я расскажу, как преобразовать код <a href="http://www.sape.ru/r.e0bd7fc3a8.php" target="_blank">сапы</a> таким образом, чтобы рекламный блок на Вашем сайте вообще не показывался, если ссылок нет. Если непонятно, что я имею в виду &#8211; обратите внимание на этот блог. В сайдбаре в левой половине в самом низу на главной странице есть блок &laquo;реклама&raquo;, где размещаются ссылки. На других страницах блока нет. Он появляется автоматически только если ссылки для этой страницы куплены в <a href="http://www.sape.ru/r.e0bd7fc3a8.php" target="_blank">сапе</a>.</p>
<p><span id="more-211"></span></p>
<p>Я решил написать эту статью, т.к. на многих сайтах видел подобные ошибки. Если бы я сделал не так, как здесь напишу, то мой блок &laquo;реклама&raquo; висел бы пустым на тех страницах, гды ссылок не купили.</p>
<p>Кроме того, открываются неограниченные возможности по редактированию самих ссылок. Например, можно вырезать весь текст, кроме ссылки, можно выводить ссылки не через разделитель, а списком, на новой строке. В общем, на что хватит фантазии. Но пока что о рекламном блоке :)</p>
<p>Итак, понятно, что для осуществления поставленной задачи нужно для начала узнать &#8211; пришли ли к нам ссылки из <a href="http://www.sape.ru/r.e0bd7fc3a8.php" target="_blank">сапы</a>. Делаем примерно как в <a href="http://dimoning.ru/money/sapa-vyidaet-saytyi/" target="_blank">прошлой статье</a>, но чуть по-другому:</p>
<pre><code class="php">
$a = $sape-&gt;return_links();
if (!empty ($a)) {}
</code></pre>
<p>Сначала мы &laquo;выводим&raquo; ссылки в переменную $a (а не на сайт, как обычно), после мы проверяем, является ли $a пустой (с помощью функции <a href="http://ru.php.net/manual/ru/function.empty.php" target="_blank">empty</a>) и если не является, то выполняется код, заключенный в { и }.</p>
<p>Конечно, в фигурные скобки и нужно включать оформление блока для ссылок! Теперь то, что получается в итоге. У меня это выглядит так:</p>
<pre><code class="php">
if (!defined('_SAPE_USER')){
    define('_SAPE_USER', '.....');
}
require_once($_SERVER['DOCUMENT_ROOT'].'/'._SAPE_USER.'/sape.php');
$sape = new SAPE_client();
$a = $sape-&gt;return_links();
if (!empty ($a)){
    ?&gt;
    &lt;br&gt;&lt;br&gt;
    &lt;div class="menu_block l"&gt;
    &lt;div class="title_menu_block"&gt;Реклама&lt;/div&gt;
         &lt;?php echo $a; ?&gt;
    &lt;/div&gt;
    &lt;?php
}
</code></pre>
<p>Теперь весь блок выводится только, если <a href="http://www.sape.ru/r.e0bd7fc3a8.php" target="_blank">сапа</a> отправляет нам какие-то ссылки.</p>
<p>Еще одно замечание: в <a href="http://dimoning.ru/money/sapa-vyidaet-saytyi/" target="_blank">предыдущей статье</a> говорилось, как изменить код сапы так, чтобы поисковикам было сложнее определить наличие сапы на сайте. Я приведу здесь общий код для оформления блока и для его защиты, а так же (возможно, кто-то не поймет сам и ему пригодится), укажу кодировку вывода UTF-8.</p>
<pre><code class="php">
&lt;?php
if (!defined('_SAPE_USER')){
	define('_SAPE_USER', '......');
}
require_once($_SERVER['DOCUMENT_ROOT'].'/'._SAPE_USER.'/sape.php');
$o['charset'] = 'UTF-8';
$sape = new SAPE_client($o);
unset($o);
$a = $sape-&gt;return_links();
if (substr_count ($a, "dispenser") &lt;= 0){
	if (!empty ($a)){
	?&gt;
		&lt;br&gt;&lt;br&gt;
		&lt;div class="menu_block l"&gt;
			&lt;div class="title_menu_block"&gt;Реклама&lt;/div&gt;
			&lt;?php echo $a; ?&gt;
		&lt;/div&gt;
	&lt;?php
	}
}
?&gt;
</code></pre>
<p>Вот так. Теперь у нас защищенный блок ссылок, который не выводится вовсе, если ссылок нет. Удачи! :)</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/esli-sape-ssyilok-net.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Сапа выдает поисковикам сайты, где продают ссылки!</title>
		<link>http://dimoning.ru/sapa-vyidaet-saytyi.html</link>
		<comments>http://dimoning.ru/sapa-vyidaet-saytyi.html#comments</comments>
		<pubDate>Fri, 01 Aug 2008 09:06:37 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[Sape.ru]]></category>
		<category><![CDATA[Общее]]></category>
		<category><![CDATA[на PHP]]></category>
		<category><![CDATA[на WordPress]]></category>
		<category><![CDATA[насчет Sape]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=207</guid>
		<description><![CDATA[Слава богу, &#171;выдает&#187; она их косвенным образом. Но все равно очень глупым. Такой косяк был замечен на очень многих сайтах, и мне кажется, что поисковики просто не могли не воспользоваться случаем. Здесь я напишу, в чем дело и как от этого защититься.
Собственно дело в том, что сервера сапы сейчас сильно нагружены, а в некоторые моменты [...]]]></description>
			<content:encoded><![CDATA[<p>Слава богу, &laquo;выдает&raquo; она их косвенным образом. Но все равно очень глупым. Такой косяк был замечен на очень многих сайтах, и мне кажется, что поисковики просто не могли не воспользоваться случаем. Здесь я напишу, в чем дело и как от этого защититься.</p>
<p>Собственно дело в том, что сервера сапы сейчас сильно нагружены, а в некоторые моменты перегружены. И тупые программисты сапы (вот уж тут по праву назову их тупыми) сделали так: если скрипт не может достучаться до сервера раздачи ссылок, он <strong>прямо на сайт</strong> выдает ошибку со словами (цитирую):</p>
<p><span id="more-207"></span></p>
<p><span>SAPE_ERROR: Не могу подключиться к серверу: dispenser-01.sape.ru/code.php?user=b4c4045f147bf074f5dcd938cd734316&amp;host=goriz.ru</span></p>
<p>Поисковику даже задумываться не о чем &#8211; уже все понятно. Сайт торгует ссылками. Кстати, посмотрите на выдачу по запросу dispenser-01.sape.ru/code.php?user=, dispenser-02.sape.ru/code.php?user= и другим (меняется цифра от нуля до количества сапо-серверов) &#8211; возможно Ваш сайт там есть ;)</p>
<p>Сейчас немного программерского бреда. Это для программеров. Защищенный код будет приведен в конце ;) Это для нормальных людей :)</p>
<p>Теперь о защите. Как защититься? Во первых, не выводить ссылки сразу, а записывать их в переменную. Во-вторых, проверять в этой переменной вхождение строки &#8216;dispenser-&#8217;. В обычных ссылках такой нет, а в этой тупой ошибке &#8211; есть. И если эта строка нашлась, не выводить ничего. Если не нашлась &#8211; выводить ссылки.</p>
<p>Для проверки вхождения мы будем пользоваться функцией int <strong>substr_count</strong> (string $haystack, string $needle) &#8211; &laquo;<strong>substr_count()</strong> Возвращает число вхождений подстроки needle  в строку haystack . Заметьте, что поиск ведется с учетом регистра символов.&raquo; (c) php.net. Если ничего не нашли, то вернется 0.</p>
<p>Теперь в коде сапы нужно заменить строку echo $sape-&gt;return_links(); на следующий код:</p>
<pre><code class="php">
$a = $sape-&gt;return_links();
if (substr_count ($a, "dispenser") &lt;= 0){
	echo $a;
}else{
	echo "Hello, Yandex! :)";
}
</code></pre>
<p>Хело, Яндекс &#8211; это, конечно, шутка. ;) Сгенерировать эту ошибку специально невозможно. Но можно проверить работоспособность кода хотя бы специально подставив в переменную $a строку с этой ошибкой до проверки. Например так:</p>
<pre><code class="php">
$a = $sape-&gt;return_links();
//разделено на строки для лучшего чтения
$a = "SAPE_ERROR: Не могу подключиться к серверу:
     dispenser-01.sape.ru/code.php?user=
     f72e534919cd569065c0994725491ce3&amp;host=kitaphana.kz,
     type: file_get_contents";
if (substr_count ($a, "dispenser") &lt;= 0){
	echo $a;
}else{
	echo "Hello, Yandex! :)";
}
</code></pre>
<p>Выводит Hello, Yandex :), а значит защита сработала.</p>
<p>UPD: Блин, совсем забыл! Hello, Yandex лучше удалить нафиг. Можно вообще удалить блок else, тогда код получится таким:</p>
<pre><code class="php">
$a = $sape-&gt;return_links();
if (substr_count ($a, "dispenser") &lt;= 0){
	echo $a;
}
</code></pre>
<p>Собственно, как хотите &#8211; можно оставить и послание. Можно просто убрать все из вывода (сделать echo &laquo;&raquo;;) в блоке else. Да, и еще &#8211; любителям &laquo;псевдо-рефакторинга&raquo; &#8211; можно и не использовать переменную $a, да. Но так же понятнее ;)</p>
<p>Удачи в заработках! :)</p>
<p>____________________________________________</p>
<p>Представляю Вам блог с интересным названием <a href="http://disdain.ru">Здесь презирают заработок в Интернете.</a> Порадовали циничное отношение к манимейкингу, но все записи &laquo;по делу&raquo;, как ни странно ;).</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/sapa-vyidaet-saytyi.html/feed</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>Загрузка каталога файлов на FTP с помощью PHP.</title>
		<link>http://dimoning.ru/ftp-upload-by-php.html</link>
		<comments>http://dimoning.ru/ftp-upload-by-php.html#comments</comments>
		<pubDate>Sat, 28 Jun 2008 20:57:31 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=142</guid>
		<description><![CDATA[Сегодня хочу рассказать Вам как можно загрузить каталог файлов на FTP с помощью PHP. Задача не тривиальна тем, что кроме непосредственной загрузки файла нужно обходить весь каталог рекурсивной функцией и загружать все файлы (т.к. списка файлов в каталоге изначально нет).
Где может использоваться такой скрипт? Я написал его себе, т.к. мне надоело постоянно вручную загружать один [...]]]></description>
			<content:encoded><![CDATA[<p>Сегодня хочу рассказать Вам как можно загрузить каталог файлов на FTP с помощью PHP. Задача не тривиальна тем, что кроме непосредственной загрузки файла нужно обходить весь каталог рекурсивной функцией и загружать все файлы (т.к. списка файлов в каталоге изначально нет).</p>
<p>Где может использоваться такой скрипт? Я написал его себе, т.к. мне надоело постоянно вручную загружать один и тот же движок на разные сайты (сателлиты), гораздо легче указать 20 доменов скрипту и уйти пить чай, а не сидеть перед компьютером. Или нет? O_o</p>
<p><span id="more-142"></span></p>
<p>Чтобы PHP научился работать с FTP нужно:<br />
<strong> Для Linux:</strong> при инсталляции указать флаг: &#8211;enable-ftp<br />
<strong>Для Windows:</strong> поддержка работы с FTP устанавливается по умолчанию.</p>
<p>Следующий шаг, который придется сделать, это отключить лимит времени выполнения скрипта. Понятно, что файлов для загрузки может быть много или даже очень много, поэтому нельзя ограничивать скрипт стандартными 30 секундами работы. Напоминаю, что отключается это в php.ini в строке <strong>max_execution_time</strong>, ее нужно установить равной нулю. Можно, конечно, воспользоваться функцией <strong>set_time_limit  (0)</strong>, но я предпочитаю ее не использовать.</p>
<p>Теперь переходим к созданию самого скрипта. Скрипт будет состоять из двух больших частей &#8211; функции обхода каталога и подключения и загрузки на FTP. Наверняка скрипт можно оптимизировать, можно вообще поменять разные куски кода &#8211; я, опять же, писал так, как мне удобнее его использовать.</p>
<p><strong>Шаг 1: Пишем скрипт обхода каталога.</strong></p>
<p>Ну, то есть как пишем&#8230; Никак не пишем. Вот он:</p>
<pre><code class="php">
//Загружает файлы
function my_upload($new_dir){
	$files = glob("*");
	foreach ($files as $file){
		if ($file == "." || $file == "..") continue;

		echo "$file, "; flush();

		if (is_dir ($file)){
			chdir ($file);
			my_upload ($file);
			chdir ("..");
		}
	}
}
</code></pre>
<p>Как функция работает? Сначала получаем список всех файлов в данной категории в массив $files с помощью функции <a href="http://ru2.php.net/manual/en/function.glob.php" target="_blank">glob()</a>. Эта функция на самом деле очень клевая, я недавно о ней узнал и очень рад. Теперь всякие там opendir, readdir и прочее отдыхают.</p>
<p>Разбираем этот массив по элементам ($file, там содержится имя очередного файла или категории): если это точка или двоеточие (что означает родительскую категорию и переход на уровень вверх соответственно) &#8211; сразу пропускаем этот шаг цикла (т.к. это не файлы и работать с ними не получится). Дальше выводим имя текущего файла в браузер для наглядности работы (позже здесь будет загрузка на FTP). Если не использовать функцию <a href="http://ru2.php.net/manual/en/function.flush.php" target="_blank">flush()</a>, то возникнет эффект зависания.</p>
<p>Дальше, мы проверяем, является ли этот файл директорией. Если является, то мы переходим в нее и опять вызываем эту же функцию обхода. Таким образом получается: читаем файлы в текущем каталоге, если очередной файл &#8211; каталог, переходим в него и читаем все там и так далее. Причем, заметьте, когда мы вызываем функцию второй раз и она заканчивает свою работу, то она возвращает управление в главную функцию. То есть с точки зрения первой <a href="http://ru.wikipedia.org/wiki/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F" target="_blank">итерации</a> (первого вызова функции) это выглядит так: мы читаем каталог, нарываемся на подкаталог, вызываем какую-то функцию, она там что-то делает и мы продолжаем дальше читать каталог. Ну это грубо говоря :) Как объяснить понятнее, я не знаю.</p>
<p>Конечно, после того, как мы ушли на каталог вниз и вызвали функцию рекурсивно, нам нужно перейти обратно, чтобы читать файлы дальше (это к слову о вызове chdir (&laquo;..&raquo;);).</p>
<p>Использовать эту функцию придется следующим образом (подобно тому, как она использует сама себя при рекурсии):</p>
<pre><code class="php">chdir ("dir_to_upload");
@my_upload();
echo "ок.";</code></pre>
<p>То есть переходим в каталог (относительно места расположения скрипта), который нам нужно загрузить на FTP и вызываем функцию загрузки.</p>
<p><strong>Шаг 2, Встраиваем загрузку на FTP.</strong></p>
<p>Теперь нужно установить соединение с FTP и по мере обхода файлов загружать их. Причем, понятно, что директории придется создавать вручную. Но ничего сложного здесь нет (как и выше).</p>
<p>Для начала нужно установить соединение с сервером, залогиниться и подготовиться к отправке файлов. Это делается так:</p>
<pre><code class="php">
$connect = ftp_connect ($host);
if (!$connect)
	die ("Не удалось установить соединение.");

if (!ftp_login ($connect, $user, $password))
	die ("Не подключились.");

// ftp_chdir ($connect, $directory);

chdir ("dir_to_upload");
@my_upload();

if ($connect) ftp_quit ($connect);
</code></pre>
<p>Имена функций прекрасно переводятся с английского, поэтому комментировать даже не хочется. Уточню, что закомментрированная строчка ftp_chdir нужна, если Вы хотите загрузить файлы в определенный каталог ($directory там как раз и есть имя каталога). Вызов функции загрузки прокомментирован выше.</p>
<p>Так&#8230; Да, еще нужно опять поменять функцию обхода, добавив в нее загрузку файлов. Теперь она выглядит так:</p>
<pre><code class="php">
global $connect;

$files = glob("*");
foreach ($files as $file){
	if ($file == "." || $file == "..") continue;

	echo "| "; flush();

	if (is_file ($file)){
		ftp_put ($connect, $file, $file, FTP_BINARY);
	}

	if (is_dir ($file)){
		ftp_mkdir ($connect, $file);
		chdir ($file);
		ftp_chdir ($connect, $file);
		my_upload ($file);
		ftp_chdir ($connect, "..");
		chdir ("..");
	}
}
</code></pre>
<p>Комментарии по поводу новых строчек кода. Делаем глобальным дескриптор подключения к ftp ($connect), нам ведь нужно использовать уже установленное поделючение (если Вы оформили загрузку не в виде функции, то это не нужно). Опять, как обычно, читаем файлы. Но теперь, вместо вывода файла мы его загружаем. Проверка, файл ли это, осуществляется функцией is_file(), и если файл &#8211; загружаем его с помощью функции ftp_put (первый параметр &#8211; соединение, второй &#8211; конечное имя файла, третий &#8211; локальное имя файла, четвертый &#8211; тип загрузки). По идее для передачи изображений нужно использовать FTP_BINARY, а для передачи текста FTP_ASCII, но у меня все нормально работает и просто только при FTP_BINARY O_o</p>
<p>Ну и, если нашли каталог, то создаем его на FTP с помощью функции ftp_mkdir(), переходим в него, заливаем файлы, выходим из него. Дальше все без изменений.</p>
<p><strong>Эпилог. </strong>Загрузить каталог средствами PHP по FTP у меня не вышло, пришлось писать рекурсивную функцию (что я здесь Вам и представил). Вполне может быть, что я пропустил какую-то функцию, которая сама все это делает и не нужно писать огромные километры кода, но не нужно тыкать в меня пальцем и смеяться, т.к. я все равно считаю, что мой способ лучше, т.к.:</p>
<p>1) развивает голову (самый важный <strong>о</strong>рган у программиста, после попы и пальцев, конечно);<br />
2) здесь у меня в нее встроен индикатор загрузки (вывод вертикальной палки по мере обхода цикла как символ того, что все работает нормально и загрузка идет; одна палочка &#8211; один файл загружен);<br />
3) можно встроить дополнительные бонусы, например, возможно пропускать файлы с определенным расширением, с определенными именами и прочее и прочее.</p>
<p>Я отметил интересные функции ссылками на их описания. Но очень рекомендую при непонятках с другими функциями не игнорировать &laquo;великий источник знаний&raquo;, а все же <a href="http://php.net" target="_blank">пойти в мануал</a>. :) Если что непонятно, как всегда &#8211; на все вопросы постараюсь ответить, пишите в комментариях.</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/ftp-upload-by-php.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Подключаемся к SSH2.0 через PHP.</title>
		<link>http://dimoning.ru/ssh2-php.html</link>
		<comments>http://dimoning.ru/ssh2-php.html#comments</comments>
		<pubDate>Thu, 26 Jun 2008 11:18:46 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/?p=136</guid>
		<description><![CDATA[Возникла недавно такая задача &#8211; нужно было подключиться к серверу, где установлен SSH2.0, но не через стандартный клиент (например, какой-нибудь Putty), а через скрипт PHP. Соответственно, на сокетах делать не получилось &#8211; разбираться в самом протоколе SSH2.0, это можно свернуть себе мозг. Желательно было найти какой-то стандартный скрипт/класс/модуль. Кстати, нашелся модуль, работающий с SSH1.0 &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>Возникла недавно такая задача &#8211; нужно было подключиться к серверу, где установлен SSH2.0, но не через стандартный клиент (например, какой-нибудь Putty), а через скрипт PHP. Соответственно, на сокетах делать не получилось &#8211; разбираться в самом протоколе SSH2.0, это можно свернуть себе мозг. Желательно было найти какой-то стандартный скрипт/класс/модуль. Кстати, нашелся модуль, работающий с SSH1.0 &#8211; класс на &laquo;pure PHP&raquo; (чистом PHP), но он не подошел по понятной причине (на сервере-то SSH2.0). Искал дальше, и вот что вышло.</p>
<p><span id="more-136"></span></p>
<p>Недолгие поиски по буржунету привели меня к тому, что был найден дополнительный модуль для PHP, позволяющий работать с SSH2.0. Этот модуль (простите, я обозвал расширение модулем), как и всякий другой копируется в соответствующую директорию PHP, дальше нужно в php.ini прописать его. Кстати, я работаю под Vista, так что извиняйте.</p>
<p><strong>Установка в Windows.</strong></p>
<p>Модуль можно скачать здесь: <a href="http://snaps.php.net/" target="_blank">http://snaps.php.net/</a>, выберите там свою версию PHP и скачайте pecl-пак (в нем содержатся всякие разные прикольные модули).</p>
<p>Действия вполне стандартные и понятные. Брем из скачанного архива файл php_ssh2.dll, копируем его в каталог с расширениями (у меня тут C:/program files/php/exts/). Дальше открываем файл C:/windows/php.ini, находим строчки с подключением модулей, ну и дописываем, понятное дело &#8211; extension=php_ssh2.dll.</p>
<p>Обычно я перезапускаю апач, хотя, по идее, это не требуется.</p>
<p><strong>Установка в Unix/Linux.</strong></p>
<p>* я не отвечаю за успешность следующих шагов, т.к. сам под Linux эту библиотеку не компилировал ни разу</p>
<p>Сначала качаем и собираем библиотеку:</p>
<pre><code>
cd /usr/src
wget http://surfnet.dl.sourceforge.net/
          sourceforge/libssh2/libssh2-0.14.tar.gz
tar -zxvf libssh2-0.14.tar.gz
cd libssh2-0.14/
./configure
make all install
</code></pre>
<p>Дальше связываем PHP и эту новую собранную библиотеку:</p>
<pre><code>pecl install -f ssh2</code></pre>
<p>Дальше опять же &#8211; открываем php.ini и дописываем туда extension=ssh2.so</p>
<p><strong>Использование php_ssh2.dll</strong></p>
<p>Сначала код, поясню позже:</p>
<pre><code class="php">
$host = "site.ru";
$user = "user";
$pass = "password";

function exec_ssh ($command){
	global $con;
		if (!$stream = ssh2_exec($con, $command)){
			die ("fuck");
		}else{
			stream_set_blocking($stream, true);
			$data = "";
			while($o = fgets($stream)){
				$data .= $o;
			}
			fclose($stream);
        }
		return $data;
}

if (!function_exists("ssh2_connect"))
       die("function ssh2_connect doesn't exist");

if(!($con = ssh2_connect($host, 22))){
    echo "unable to connect\n";
} else {
    if(!ssh2_auth_password($con, $user, $pass)) {
        echo "unable to auth\n";
    } else {
		echo "logged in!\n";
		echo exec_ssh ("ls");
    }
}

echo $data;
</code></pre>
<p>Код частично передран с найденных сайтов, некоторые вещи &#8211; лично мои. Итак.</p>
<p>Сначала оставим функцию exec_ssh(), пойдем дальше. Для начала скрипт проверяет, существует ли функция ssh2_connect &#8211; если ее нет, значит новый модуль не работает или не верно подключился. Дальше скрипт пытается установить соединение с хостом по порту 22 с помощью функции ssh2_connect и сохраняет дескриптор соединения в $con. Если все прошло успешно, мы пытаемся авторизоваться, отсылая в <em>соедниение $con</em> логин и пароль. Если авторизация успешна, пишем, что вошли и можно начинать выполнять команды.</p>
<p>Теперь по функции exec_ssh(); Понятно, эта функция создана специально, чтобы выполнять команды на удаленном сервере. В качестве результата она возвращает то, что выдал ей сервер в ответ. В данном случае она выполняет команду ls и полученный список файлов в текущей директории выводит в браузер.</p>
<p>Как она работает? Для начала, понятно, что нам нужно отдавать команды в определенное соединение (здесь &#8211; $con). Я его сделал глобальным, мне так удобнее (можно передавать через параметр, например).  &laquo;Родная&raquo; функция ssh2_exec выполняет команды, посланные в соединение и возвращает результат. То есть &#8211; выполняем ssh2_exec с нужной командой, если она выполнилась успешно, можно начинать ожидать ответа с сервера. Смысл stream_set_blocking в том, чтобы не пытаться забирать данные с сервера, если эти данные еще не поступили &#8211; через интернет пакеты летят иногда ощутимо долго. Как только данные поступили, собираем их в переменную $data вполне обычным способом (как чтение из потока, сокета или файла). И возвращает $data, то есть то, что нам отдал сервер.</p>
<p>Вроде бы со свем разобрались. Но я хотел бы акцентировать Ваше внимание еще на одном моменте.</p>
<p><strong>Важно! Почему может не работать ssh2-модуль, хотя все подключено правильно?</strong></p>
<p>Я полчаса мучился, не мог понять в чем дело &#8211; вроде бы подключил все верно, а работать отказывается, пишет, что функция не найдена. Причем сам PHP говорит, что модуль подключился и все должно работать. Я не знаю с чем это связано, но у меня этот модуль заработал, ТОЛЬКО в консоли, когда я руками вызывал php.exe. То есть &#8211; иду в консоль, захожу в каталог с PHP, пишу там:</p>
<p>&gt; php.exe D:/www/test/www/index.php &#8211; все работает. Вывод происходит тоже в консоль, разумеется. Мне даже было местами приятно, вспомнил старое Unix-программирование, да и вообще всякие hello-world&#8217;ы.</p>
<p>В общем, я Вас предупредил ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/ssh2-php.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Взаимодействие PHP и MySQL, цикл статей.</title>
		<link>http://dimoning.ru/php-mysql.html</link>
		<comments>http://dimoning.ru/php-mysql.html#comments</comments>
		<pubDate>Thu, 08 May 2008 21:52:40 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/archives/68</guid>
		<description><![CDATA[Один мой друг попросил объяснить ему, как взаимодействует PHP и база данных MySQL. Я решил помочь ему в освоении сего ужаса и написать статью-другую на эту тему. Но за одну статью, я думаю, здесь не уложиться. Более того, мой друг только начинает заниматься программированием, поэтому нужно объяснить поподробнее и попонятнее. Поэтому я решил написать как [...]]]></description>
			<content:encoded><![CDATA[<p>Один мой друг попросил объяснить ему, как взаимодействует PHP и база данных MySQL. Я решил помочь ему в освоении сего ужаса и написать статью-другую на эту тему. Но за одну статью, я думаю, здесь не уложиться. Более того, мой друг только начинает заниматься программированием, поэтому нужно объяснить поподробнее и попонятнее. Поэтому я решил написать как взаимодействует PHP и MySQL в цикле из 4ех статей.</p>
<p>Скорее всего получится так:</p>
<p>1) Установка Apache + PHP + MySQL;<br />
2) Описание базы данных MySQL (как создавать таблицы, как добавлять, удалять и изменять данные в них, философия применения базы данных в веб-приложениях);<br />
3) Как PHP взаимодействует с MySQL (какие команды PHP нужны для работы с MySQL);<br />
4) Как пример &#8211; создание простейшей гостевой книги на PHP и базе данных MySQL.</p>
<p>То есть &#8211; будет 4 статьи. Я не буду обозначать, что они из одного цикла. Названия будут разные (это в целях СЕО-оптимизации ;).</p>
<p>Ждите, и будет счастье.</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/php-mysql.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Получение HTML-кода сайта PHP-скриптом</title>
		<link>http://dimoning.ru/polu4enie-html-by-php.html</link>
		<comments>http://dimoning.ru/polu4enie-html-by-php.html#comments</comments>
		<pubDate>Tue, 06 May 2008 18:35:08 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/archives/65</guid>
		<description><![CDATA[Получить HTML-код сайта необходимо, например, при граббинге сайта. Но у меня был случай забавнее&#8230; Всем известный БашОрг забанил моего провайдера интернета за какие-то просчеты (вероятно, была дос/ддос атака от абонентов моего прова с общим IP). То есть &#8211; башорг у меня не открывался, а все остальное открывалось.
Баш почитать же очень хотелось. Поэтому я написал очень [...]]]></description>
			<content:encoded><![CDATA[<p>Получить HTML-код сайта необходимо, например, при граббинге сайта. Но у меня был случай забавнее&#8230; Всем известный <a href="http://bash.org.ru" target="_blank">БашОрг</a> забанил моего провайдера интернета за какие-то просчеты (вероятно, была дос/ддос атака от абонентов моего прова с общим IP). То есть &#8211; башорг у меня не открывался, а все остальное открывалось.</p>
<p>Баш почитать же очень хотелось. Поэтому я написал очень маленький и простой скрипт, которые хавает код башорга и выводит его в браузер. Совершенно аналогичный код используется для получения содержимого страницы при парсинге сайта.</p>
<p><span id="more-75"></span></p>
<p>&lt;?php<br />
$file = fopen (&laquo;http://bash.org.ru&raquo;, &laquo;r&raquo;);<br />
$str = &laquo;&raquo;;<br />
while (!feof ($file)){<br />
$str .= fread ($file, 512);<br />
}<br />
fclose ($file);<br />
echo $str;<br />
?&gt;</p>
<p>Сразу уточню, что чтение сайта приведенным здесь образом возможно только в случае, если в fopen можно передать адрес страницы (файла), не находящегося на данном сервере (там же где и запускается скрипт). Это регулируется в настройках интерпретатора PHP.</p>
<p>Что здесь происходит? Все точно так же, как если бы нам надо было прочитать файл. Сначала открываем баш для чтения (флаг &laquo;r&raquo;). Заводим переменную $str, в которую и запишем весь сайт. Записываем в цикле данные в $str по 256 байт, пока не кончится файл (здесь &#8211; удаленная страница). Закрываем файл и выводим на экран.</p>
<p>P.S. Этот скрипт лежит тут: <a href="http://dimoning.ru/get_bash.php" target="_blank">http://dimoning.ru/get_bash.php</a> Запустив его, кто-то удивится &#8211; почему все так уродски выглядит и напоминает баш довольно отдаленно? Потому, что файл стилей (css) не читается и не подключается. Вернее &#8211; мне было просто влом это делать, для чтения он не нужен ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/polu4enie-html-by-php.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Преобразование даты MySQL в общепринятый (человеческий) формат</title>
		<link>http://dimoning.ru/mysql-date-to-normal.html</link>
		<comments>http://dimoning.ru/mysql-date-to-normal.html#comments</comments>
		<pubDate>Fri, 11 Apr 2008 23:25:46 +0000</pubDate>
		<dc:creator>DimoninG</dc:creator>
				<category><![CDATA[на PHP]]></category>

		<guid isPermaLink="false">http://dimoning.ru/archives/31</guid>
		<description><![CDATA[Думаю, многим, кто работал с датами в своих скриптах знакома такая проблема: в MySQL дата хранится в формате ГГГГ-ММ-ДД ЧЧ:ММ:СС &#8211; и это нельзя просто так вывести пользователю, он не разберется. Нужно, чтобы дата выводилась в общепринятом (в России) формате: ДД-ММ-ГГГГ ЧЧ:ММ:СС.
Я попробовал решить эту проблему самым простым путем.
 Погуглив, я удивился: некоторые программисты пишут [...]]]></description>
			<content:encoded><![CDATA[<p>Думаю, многим, кто работал с датами в своих скриптах знакома такая проблема: в MySQL дата хранится в формате ГГГГ-ММ-ДД ЧЧ:ММ:СС &#8211; и это нельзя просто так вывести пользователю, он не разберется. Нужно, чтобы дата выводилась в общепринятом (в России) формате: ДД-ММ-ГГГГ ЧЧ:ММ:СС.</p>
<p>Я попробовал решить эту проблему самым простым путем.</p>
<p><span id="more-55"></span> Погуглив, я удивился: некоторые программисты пишут целые классы для преобразования дат и т.п. Зачем так сложно? В пределах одного проекта понадобится один-два, ну от силы три формата даты и все&#8230; Я написал одну функцию, которая меня совершенно устроила и была применена на некоторых моих сайтах.<br />
<code><br />
// Функция преобразования даты.<br />
function data_convert ($data, $year, $time, $second){<br />
$res = "";<br />
$part = explode(" " , $data);<br />
$ymd = explode ("-", $part[0]);<br />
$hms = explode (":", $part[1]);<br />
if ($year == 1) {$res .= $ymd[2]; $res .= ".".$ymd[1]; $res .= ".".$ymd[0];}<br />
if ($time == 1) {$res .= " ".$hms[0]; $res .= ":".$hms[1]; if ($second == 1) $res .= ":".$hms[2];}<br />
return $res;<br />
}<br />
</code></p>
<p>Как ее применить?  Легко. Предположим, мы прочитали что-то из БД:</p>
<p>$str = mysql_fetch_array (mysql_query (&laquo;&#8230;&raquo;));</p>
<p>И тут у нас записана дата: $str['dt'] (в формате MySQL, конечно, т.е. ГГГГ-ММ-ДД ЧЧ:ММ:СС).</p>
<p>Чтобы везде, где выводится дата, она выводилась в нужном нам формате, напишем:</p>
<p>$str['dt'] = data_convert ($str['dt'], 1, 1, 0);</p>
<p>Получаем красивую дату: ДД-ММ-ГГГГ ЧЧ:ММ.</p>
<p>Что за параметры у функции? Глядя на код и так все понятно, но поясню дополнительно: первый это дата в формате MySQL (текстовая строка), следующие три могут быть 0 или 1. Второй параметр: если 1, выводит год. Третий: если 1, выводит часы и минуты. Четвертый: если 1, выводит секунды.</p>
<p>Думаю, все довольно прозрачно.</p>
]]></content:encoded>
			<wfw:commentRss>http://dimoning.ru/mysql-date-to-normal.html/feed</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
	</channel>
</rss>

