<?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>PHP, Python, Perl, JavaScript</title>
	<atom:link href="http://inroot.ru/feed" rel="self" type="application/rss+xml" />
	<link>http://inroot.ru</link>
	<description>Об интернетах...</description>
	<lastBuildDate>Fri, 03 Feb 2012 12:53:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Переезд блога</title>
		<link>http://inroot.ru/2012-02/pereezda-bloga.html</link>
		<comments>http://inroot.ru/2012-02/pereezda-bloga.html#comments</comments>
		<pubDate>Fri, 03 Feb 2012 12:11:14 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Разное]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=817</guid>
		<description><![CDATA[Блог переезжает на домен omurashov.ru. Переезд весьма условный, тем не менее, некоторые публикации уже сейчас имеют редирект на новый домен. Далеко не все публикации окажутся на новом домене. Скорее всего, мигрирует только малая часть. Различная требуха и заметки сомнительного содержания останутся только здесь, а затем, через некоторое время, будут удалены окончательно. В новом блоге не [...]]]></description>
			<content:encoded><![CDATA[<p>Блог переезжает на домен <a href="http://omurashov.ru/" target="_blank">omurashov.ru</a>. Переезд весьма условный, тем не менее, некоторые публикации уже сейчас имеют редирект на новый домен.</p>
<p>Далеко не все публикации окажутся на новом домене. Скорее всего, мигрирует только малая часть. Различная требуха и заметки сомнительного содержания останутся только здесь, а затем, через некоторое время, будут удалены окончательно.</p>
<p>В новом блоге не будет статей в том смысле, в котором они бывают. Он будет состоять из заметок. В целом, будет соблюдена концепция блога. Никаких попыток написания учебного материала предприниматься больше не будет.</p>
<p>Как-то так.</p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2012-02/pereezda-bloga.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Обзор Acer Iconia Tab A501</title>
		<link>http://inroot.ru/2011-10/review-acer-iconia-tab-a501.html</link>
		<comments>http://inroot.ru/2011-10/review-acer-iconia-tab-a501.html#comments</comments>
		<pubDate>Sat, 01 Oct 2011 22:37:46 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Гаджеты]]></category>
		<category><![CDATA[Acer Iconia Tab A501]]></category>
		<category><![CDATA[Samsung Galaxy Tab 10.1]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=729</guid>
		<description><![CDATA[Данная заметка является продолжением другой, в которой я поведал о своем знакомстве с Samsung Galaxy Tab 10.1. Исходя из этого, я буду писать о Acer Iconia Tab A501, сравнивая его с Галакси. Именно в сравнении я выбирал новый планшет и в сравнении я буду описывать новые впечатления. Во-первых, отмечу тот факт, что средняя цена Acer [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2011/10/iconia_a501.jpg" alt="Acer Iconia Tab A501" title="Acer Iconia Tab A501" width="150" height="150" class="post_cover alignnone size-full wp-image-732" /></p>
<p>Данная заметка является <a href="/2011-09/review-samsung-galaxy-tab-10-1.html" target="_blank">продолжением другой</a>, в которой я поведал о своем знакомстве с Samsung Galaxy Tab 10.1. Исходя из этого, я буду писать о Acer Iconia Tab A501, сравнивая его с  Галакси. Именно в сравнении я выбирал новый планшет и в сравнении я буду описывать новые впечатления.</p>
<p>Во-первых, отмечу тот факт, что <strong>средняя цена Acer Iconia Tab A501</strong> на 4000 рублей ниже, чем <strong>средняя цена на Samsung Galaxy Tab 10.1</strong>. Для меня это не являлось основным критерием, но стало приятным бонусом. В конце концов, на полученную разницу можно купить аксессуары и прочую необходимую планшетную утварь. Во-вторых, планшет от Acera был в наличии во всех магазинах электроники, что позволяло никуда не ехать и сделать покупку не сильно удаляясь от дома или места работы.</p>
<p>И так, начну свой обзор по тому же принципу «перемывания костей», что был заявлен в предыдущей заметке. Начну с описания упаковки устройства.</p>
<p><span id="more-729"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<div class="aligncenter">
<a href="/wp-content/uploads/2011/10/Iconia_Tab_A501_front.jpeg" rel="lightbox" title="Acer Iconia Tab A501"><img src="/wp-content/uploads/2011/10/Iconia_Tab_A501_front-300x207.jpg" alt="Acer Iconia Tab A501" title="Iconia_Tab_A501_front" width="300" height="207" class="alignnone size-medium wp-image-749" /></a>
</div>
<p>Нельзя сказать, что Iconia Tab A501 упакован как-то по-особенному. В принципе, такая же простая коробка, как и в случае с Galaxy Tab 10.1. Но все же, нужно отдать должное, что Acer проявил несколько большую изобретательность и не стал делать упаковку, похожую на коробку от обуви. Как я уже сказал, разница невелика, но мой агрессивный настрой заставлял придираться абсолютно ко всему.</p>
<p>Комплектация тоже не блещет, но тряпочку для протирки экрана ребята таки положили, за что им респект и уважуха. Хотя, как выяснится потом, она не особо то и нужна, что позволило даже не вынимать ее из пакетика. Но присутствие тряпочки, судя по всему, нещадно уменьшило свободное пространство в коробке и его не хватило для наушников. Их в комплекте нет. Стыд и позор. Еще Acer не пожадничал различных инструкций и пользовательских гайдов. Этой макулатуры напихали целую вязанку. Даже какие-то рекламные листовки впихнули в общую кучу. Не могу сказать, что это большая заслуга, но при виде этих мануалов мне становилось спокойнее, чего не могу отметить в случае с Galaxy. Еще смутил тот факт, что на экране планшета не было защитной пленки. Уж не знаю, чей это косяк.</p>
<p>Galaxy Tab 10.1 выглядит потрясающе и соперничать с ним вряд ли кому-то под силу. <strong>Iconia Tab A501</strong> явно не из числа тех, кому стоит хоть попытаться. Планшет от Acer сильно уступает своим изяществом и, впрочем, не только Galaxy от Samsung. Но понятия о красивостях у всех разные и меня его внешний вид вполне устраивает, хоть и в восторг не приводит.</p>
<p>Конкуренция отсутствует и в вопросах взвешивания. Acer  тяжелее Samsung’а почти на две сотни грамма и эта разница не может оставаться незамеченной. Тем не менее, нужно отдать должное тому, что Acer  имеет алюминиевый корпус, в то время как Samsung выполнен полностью из пластика.  Также замечу, что избыток веса ощущается только при сравнении. Если просто пользоваться планшетом, то очень скоро его вес кажется совершенно нормальным и не вызывает ощущения дискомфорта. Хотя, для женской руки, пожалуй, он будет тяжеловат.</p>
<p>Экран у Acer’а совершенно обычный для подобных устройств. Он не выделяется чем-то особенным и не может похвастаться инновационными решениями. Но вот стеклянное покрытие меня откровенно порадовало. Оно крайне невосприимчиво к грязным рукам и практически не оставляет на себе следов. За целый день пользования устройством у меня ни разу не возникло желания протереть экран. Совершенно другие желания вызывал Samsung Galaxy Tab 10.1. Через 30 минут его экран имел такой вид, будто в него тыкали палкой колбасы, а не пальцами.</p>
<p>В предыдущем обзоре я писал, что, невзирая на некислое железо, анимация у Самсунговского планшета немного подтормаживает. Это практически незаметно, но имеет место. Acer  в этом плане ничуть не преуспел. Собственное, у них и железо одинаковое, нечему удивляться.</p>
<p>Снова я начал с тестирования производительности планшета. В числе предустановленного софта Acer Iconia Tab A501 было несколько 3D игр. Мало того, что это просто хорошие игры, в которые не грех поиграть на досуге, они еще и обладают хорошей графикой, что позволяет делать выводы о способностях устройства справляться с качественным медийным контентом. Samsung в этом плане подсунул свинью в виде нескольких казуальных хреновин, на которые смотреть- то противно.</p>
<p><strong>С 3D графикой Iconia Tab A501</strong> справляется превосходно. Никаких лагов, торможений или артефактов. Все, как по маслу. Полная версия (не демка) предустановленного NFS Shift убила почти весь мой рабочий день.</p>
<div class="aligncenter">
<a href="/wp-content/uploads/2011/10/2_1_Acer-Iconia-Tab-A501.jpg" rel="lightbox" title="Acer Iconia Tab A501"><img src="/wp-content/uploads/2011/10/2_1_Acer-Iconia-Tab-A501-300x215.jpg" alt="Acer Iconia Tab A501" title="Acer Iconia Tab A501" width="300" height="215" class="alignnone size-medium wp-image-755" style="border: #ccc 1px solid" /></a>
</div>
<p>Следующим шагом была загрузка трех видео: mp4, mkv и avi. С подключением по USB и обменом файлами между планшетом и настольным ПК не случилось никаких проблем. Для этой процедуры не потребовалась установка дополнительных драйверов и софта. Все в лучших традициях современности – воткнул гаджет в USB порт и пользуйся им как флешкой.</p>
<p>Без дополнительного софта и кодеков, предустановленный плеер смог прочитать только mp4 формат и то с очень большими тормозами. mkv и avi читать отказался. Но проблема решилась установкой приложения MX видеоплеер. При запуске MX видеоплеер предлагает докачать кодеки MX Video Player Codec (ARMv7) и, если вы согласны, открывает соответствующую страницу маркета. После установки кодеков и нового приложения просмотра видео, любые проблемы с тормозами и нечитабельными форматами решились. Avi формат проигрывается просто идеально. Чуть меньше динамики выдает mp4 и mkv, но тормозов или зависаний нет, что делает просмотр совершенно комфортным. Сам по себе MX видеоплеер исключительное приложение для просмотра фильмов и роликов на мобильном устройстве, очень рекомендую.</p>
<p>Кстати, при копировании видео на планшет, я не делал никакой предварительной конвертации. Возможно, если ее выполнить, то и штатный плеер окажется более способным.<br />
Предустановленным ПО Acer  несколько уступает Samsung’у.  Во-первых, офисный пакет представляет собой триальную версию Docs To Go, во-вторых, виртуальных клавиатур всего две и Swype пришлось ставить самостоятельно. Агрегатор социальных сервисов мне тоже не понравился. В принципе, я никогда подобным ПО не пользовался, но если бы хотел, то пришлось бы искать замену.</p>
<p>Постараюсь не терять объективности, но дальше буду рассказывать о том, чем <strong>Acer Iconia Tab A501 мне понравился больше Samsung Galaxy Tab 10.1</strong>.</p>
<p>Во-первых, Acer имеет USB порт, к которому можно подключить обычную USB клавиатуру, не докупая никаких док станций. Моя домашняя клавиатура прекрасно распозналась без танцев с бубном. Флешки тоже читаются без проблем. Хорошая возможность, если вы хотите заменить планшетом ноутбук или просто пытаетесь добиться максимального комфорта без лишних финансовых затрат. Также присутствует micro HDMI порт и гнездо для гарнитуры. К компьютеру планшет подключается через microUSB, что меня крайне порадовало, так как имеется ряд других устройств, подключаемых через этот же тип разъема, например, HTC Desire.</p>
<p>Во-вторых, присутствует поддержка карт памяти microSDHC объемом до 32 Гб. Если вы помните, то у Samsung Galaxy Tab 10.1 память не расширяема и вам придется довольствоваться объемом 16 или 32 Гб предустановленной памяти.</p>
<p>Помимо стандартного набора из Wi-Fi, 3G и Bluetooth присутствует GPS приемник с поддержкой A-GPS. Незаменимая вещь, если вы любите покидать домашний регион вашего мобильного оператора и не имеет возможности работать через дешевую 3G сеть. Теперь у меня появился отличный поводырь по дорогам зарубежья.</p>
<p>Когда я консультировался в магазинах на предмет возможностей и <strong>особенностей Acer Iconia Tab A501</strong>, все консультанты, как один, говорили о том, что время работы батареи значительно уступает Самсунговской. В принципе, это не удивительно, так как в Galaxy Tab 10.1 используется аккумулятор повышенной емкости. Но я сильно напрягся. Мне не хотелось бегать от розетки к розетке, так как Acer от USB тоже не заряжается.</p>
<p>Батарее я уделил особое внимание и пристально наблюдал за тем, как быстро она разряжается при той или иной интенсивности пользования устройством. Если кратко, то батарея очень даже ничего и зря меня пугали. Во-первых, у Acer’а вменяемая автобалансировка яркости экрана, что позволяет значительно уменьшить расход энергии. Аналогичная функция Samsung&#8217;а работает совершенно странным образом. Жалобы на непонятный принцип регулировки яркости присутствуют практически в любом <strong>обзоре Samsung Galaxy Tab 10.1</strong>. Такие же жалобы я слышал  от продавцов-консультантов, в довершении, подтверждаю их лично. Галакси вырубает яркость на минимум и не понятно, что дальше. Я так и не смог эмулировать ситуацию, при которой он бы увеличил ее. Видимо, нужные какие-то особые условия освещенности. Acer  в этом плане совершенно адекватен и с момента включения автобалансировки ни разу не возникало желания ее выключить.</p>
<p>Статистику пользования устройством и расход энергии батареи я запечатлел на скриншотах для большей наглядности.</p>
<div class="aligncenter">
<a href="/wp-content/uploads/2011/10/device-2011-09-30-063530.png" rel="lightbox"><img src="/wp-content/uploads/2011/10/device-2011-09-30-063530-300x187.png" alt="" title="device-2011-09-30-063530" width="300" height="187" class="alignnone size-medium wp-image-734" /></a><br />
<b>Общая статистика</b></p>
<p><a href="/wp-content/uploads/2011/10/device-2011-09-30-063542.png" rel="lightbox"><img src="/wp-content/uploads/2011/10/device-2011-09-30-063542-300x187.png" alt="" title="device-2011-09-30-063542" width="300" height="187" class="alignnone size-medium wp-image-739" /></a><br />
<b>Работа экрана устройства</b></p>
<p><a href="/wp-content/uploads/2011/10/device-2011-09-30-063553.png" rel="lightbox"><img src="/wp-content/uploads/2011/10/device-2011-09-30-063553-300x187.png" alt="" title="device-2011-09-30-063553" width="300" height="187" class="alignnone size-medium wp-image-741" /></a><br />
<b>Режим ожидания</b></p>
<p><a href="/wp-content/uploads/2011/10/device-2011-09-30-063602.png" rel="lightbox"><img src="/wp-content/uploads/2011/10/device-2011-09-30-063602-300x187.png" alt="" title="device-2011-09-30-063602" width="300" height="187" class="alignnone size-medium wp-image-743" /></a><br />
<b>Работа ОС Android</b></p>
<p><a href="/wp-content/uploads/2011/10/device-2011-09-30-063612.png" rel="lightbox"><img src="/wp-content/uploads/2011/10/device-2011-09-30-063612-300x187.png" alt="" title="device-2011-09-30-063612" width="300" height="187" class="alignnone size-medium wp-image-745" /></a><br />
<b>Игра NFS Shift</b></p>
<p><a href="/wp-content/uploads/2011/10/device-2011-09-30-063621.png"  rel="lightbox"><img src="/wp-content/uploads/2011/10/device-2011-09-30-063621-300x187.png" alt="" title="device-2011-09-30-063621" width="300" height="187" class="alignnone size-medium wp-image-747" /></a><br />
<b>Связь с сетью</b></p>
</div>
<p>К сожалению, по непонятным мне причинам, сборщик статистики не зафиксировал работу с некоторыми приложениями, например, браузером и видео плеером. Также в отчет не попало время работы с Wi-fi сетями и чтение книг. Наверное, оно было незначительным на фоне энергозатрат на другие приложения и модули. Тем не менее, суммарно составило порядка 2-3 часов активности планшета. Сколько устройство работало от батареи, можете видеть по скринам. Меня результаты удовлетворили полностью.</p>
<p>Время зарядки от 4% и до 100% заняло около полутора часа, что в 3 раза меньше, чем полная зарядка Samsung Galaxy Tab 10.1, которая длится порядка 5 часов.</p>
<p>Что еще можно добавить с казанному? Я полностью доволен покупкой. Acer Iconia Tab A501 оправдал все мои ожидания и я рад, что не оставил у себя планшет от Samsung&#8217;а. Все познается в сравнении и мне не жаль того времени, что я потратил на поиски приемлемого для себя планшетного компьютера. Если вы тоже стоите перед выбором и не знаете, что купить, я крайне советую обратить свое внимание на продукт от Acer а. Да, быть может он не такой элегантный и вычурный, как  Samsung Galaxy Tab 10.1, но зато даст фору во всем остальном. Если вы ищите устройство, успешно сочетающее рабочий инструмент и центр развлечений, я думаю, вы не пожалеете, остановив выбор на Acer Iconia Tab A501.</p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-10/review-acer-iconia-tab-a501.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Обзор Samsung Galaxy Tab 10.1</title>
		<link>http://inroot.ru/2011-09/review-samsung-galaxy-tab-10-1.html</link>
		<comments>http://inroot.ru/2011-09/review-samsung-galaxy-tab-10-1.html#comments</comments>
		<pubDate>Tue, 27 Sep 2011 05:41:30 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Гаджеты]]></category>
		<category><![CDATA[Samsung Galaxy Tab 10.1]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=723</guid>
		<description><![CDATA[Недавно приобрел планшетник Samsung Galaxy Tab 10.1. Сразу скажу, что впечатления двойственные и их совокупность меняла свою полярность то в одну, то в другую сторону на протяжении всего знакомства с девайсом. Нет, безусловно, положительных эмоций больше, нежели любых других. Но, как говорится, я ожидал большего. Предвкушал некую безграничную эйфорию, а в итоге впечатления оказались достаточно [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2011/09/samsung-galaxy-tab-10-1-p7510-150x150.jpg" alt="" title="samsung-galaxy-tab-10-1-p7510" width="150" height="150" class="post_cover alignnone size-thumbnail wp-image-724" /></p>
<p>Недавно приобрел планшетник Samsung Galaxy Tab 10.1. Сразу скажу, что впечатления двойственные и их совокупность меняла свою полярность то в одну, то в другую сторону на протяжении всего знакомства с девайсом.</p>
<p>Нет, безусловно, положительных эмоций больше, нежели любых других. Но, как говорится, я ожидал большего. Предвкушал некую безграничную эйфорию, а в итоге впечатления оказались достаточно приземленными. Может быть, прошел тот возраст, когда дорогая игрушка повергала в коматозную радость и заставляла писать кипятком от одного своего вида. А может, действительно, есть поводы для огорчений.</p>
<p>И так, начнем с упаковки. Она достаточно проста. Если выражаться точнее, то проще вряд ли можно что-то придумать. Я как-то привык к тому, что дорогие девайсы пакуют в красивые и хитрые коробки, которые открываются, выполняя тройной прыжок-переворот, исполняя интернационал голосами хора МВД России. Например, блок питания, который я покупал около года назад, был облачен в очень изящную, весьма оригинально собранную коробку, крышка которой фиксировалась липучками и имела окошко из плотного прозрачного пластика. Все это бесполезные рюшечки, но видимо, я из тех людей, которые все еще встречают по одежке.</p>
<p><span id="more-723"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Комплектация, в которой планшет попал ко мне, также ничем интересным не радует. Расстроило отсутствие тряпочки для протирания экрана, который, к слову, пачкается очень быстро. Никаких чехлов, само собой, тоже не было. Хотя на чехол я и не надеялся. С девайсом поставлялось всего ничего: адаптер для зарядки, USB шнур, наушники и тонкая брошюрка-инструкция, по содержимому которой можно смело предположить, что Samsung кладет ее в комплектации всех своих мобильных устройств, в том числе и телефонов. За наушники спасибо, не ожидал. Это таки не телефон и поставлять с планшетом гарнитуру никто не обязан, мне кажется, но положили.</p>
<p>Достаем планшет из коробки и наслаждаемся. Лично я получил массу удовольствия от тактильного контакта с этим гаджетом. Исполнение действительно на высоте. Приятная плавные линии, малый вес и действительно малая толщина производят впечатление. Не расстраивает даже то, что устройство полностью из пластика. В руке планшет лежит хорошо, не оставляя и намека на то, что он может соскользнуть с ладони.</p>
<p>Включаем девайс. В каком-то из обзоров я читал, что Samsung Galaxy Tab 10.1 включается ровно 40 секунд. Специально обратил внимание на время, которое проходит с момента нажатия клавиши питания и до появления экрана блокировки – секунд 10, не более. Может быть, я как-то неправильно его включаю? :)</p>
<p>Яркие обои экрана блокировки позволяют прочувствовать всю прелесть матрицы, установленной на <strong>Samsung Galaxy Tab 10.1</strong>. Качество и насыщенность изображения действительно впечатляют. Не зря Samsung так активно акцентировали внимание на этом моменте.</p>
<p>За экраном блокировки кроется первая ложка дегтя. Что не говори, а различные анимационные эффекты чуточку, но притормаживают. Возможно, если специально не обращать на это внимание, то и не заметишь, но я очень долго скролил различные списки и вертел виртуальные рабочие столы именно с целью выявления отрывистости анимации.</p>
<p>Я не буду перечислять и описывать приложения, идущие в стандартной поставке. Без внимания останется панель настроек и прочая лирика, имеющая отношение к программному обеспечению. Об этом и так немало написано, а что касается настроек, то они, в большинстве своем, стандартные для любых android устройств и данный планшет не исключение.<br />
Первое, что я захотел проверить – проигрывание видео и аудио файлов. В конце концов, мы имеем устройство с двухядерным процессором и будет очень грустно, если медиа контент окажется ему не по зубам. Тут то и начинается все самое интересное.</p>
<p>Подключив планшет по к USB порту, я сразу попытался закинуть на него несколько фильмов, каждый из которых был гигабайта по полтора. Буквально через несколько секунд процесс копирования сгенироровал ошибку, в которой говорилось, что устройство отключено или не отвечает. На самом планшете проблема давала о себе знать зависшим индикатором синхронизации. Переподключил устройство и предпринял еще одну попытку. Несложно догадаться, что и она не увенчалась успехом. Правда на этот раз девайс сообщил мне, что <strong>MTP приложение</strong> (судя по всему, это какой-то сервис, реализующий трансфер по <strong>MTP протоколу</strong>) зависло и предложил принудительно его закрыть. Погуглив минут 20 я убедился, что не только я столкнулся с подобной проблемой, но вот четкого руководства для ее решения никто не давал. Проблема, на самом деле, не в самом планшете, а по большей части в драйверах Windows. Основными страдальцами оказались владельцы устройств от Samsung и Nokia. Именно их перу принадлежали все найденные мною обсуждения в форумах. Конкретно о проблеме с Samsung Galaxy Tab 10.1 нигде не упоминалось. Наверное, ввиду относительной новизны гаджета.</p>
<p>Мне от всего этого легче не было и негативные впечатления от знакомства с Samsung Galaxy Tab 10.1 превращались в снежный ком. Я бы мог обвинить Windows и ее драйвера или даже Android и его реализацию протоколов, но это не первое мое устройство на базе Google Android, но первое, с которым у меня возникают такие вот проблемы. Я считаю, что планшет за 25000 рублей не должен вот так вот нагибать пользователя и заставлять его тратить время на поиск путей к отступлению.</p>
<p>Ушло немало времени, пока я нашел подходящий драйвер. Проблема исчезла, и файлы стали нормально заливаться на SD карту планшета. Тем не менее, спустя некоторое время, компьютер все равно потерял подключение к планшету, хотя сам планшет все еще считал, что он соединен по USB. При дальнейшем использовании проблема повторно не возникала, поэтому предположим, что это был какой-то фантомный глюк или я что-то не то нажал.</p>
<p>В общем, мне удалось залить три фильма в разных форматах: avi, mp4 и mkv. По заявлениям Samsung, все эти форматы должны проигрываться штатным плеером без каких-либо дополнительных плясок с бубном. Конвертацию файлов, которая предлагается при копировании на устройство, я не делал. В итоге, в числе прочитанных оказался только avi файл. Mp4 и mkv плеер не осилил. Правда, повторная загрузка mp4 с конвертацией позволила прочитать и его. Но стоит ли говорить, что конвертация ну ОЧЕНЬ длительный процесс. Файл размером 1.4 Гб конвертировался около двух часов. Это чуть больше, чем длиться сам фильм, который я закачивал :). Avi видео немного подтормаживает, если сравнивать просмотр того же ролика на настольной машине. Дискомфорта это не создает, так как подтормаживания совсем незначительные, но факт имеет место.</p>
<p>Что еще можно отнести к минусам? Нет слота для карты памяти. Иначе говоря, 16 гигабайт – это все, на что вы можете рассчитывать на протяжении всего пользования планшетом. Да, есть док станция, к которой можно подключить флешку, но это не то. Да и док станцию придется покупать отдельно. Планшетов с объемом памяти в 32 гигабайт пока в продаже не видел. Зарядка только от сети. От USB устройство не заряжается. Родной USB шнурок достаточно короткий и подключать его к системнику, стоящему под столом, жутко неудобно. Планшет приходится или на пол класть или держать на самом краю стола. Ввиду того, что у шнура специфичный разъем, заменить его на более длинный не получится. Вообще с аксессуарами на текущий момент ситуация плачевна. Их попросту нет. Даже чехол или защитную пленку не найти. Конечно, со временем, все это поступит в продажу, но если хотите все и сразу, то облом. Прошивка сыровата, конечно. Но это поправимо скорыми обновлениями, благо, Google Android развивается завидно быстрыми темпами, а аппаратная начинка Samsung Galaxy Tab 10.1 позволяет надеяться, что устройство сможет получить еще не одно обновление.</p>
<p>Что в итоге? Розовые очки быстро перестали быть розовыми и пришлось спуститься на землю. Кричать о том, что я счастливый обладатель крутого планшета как-то не открывается рот. Может, я сильно придираюсь и просто замечтался, а реальность, вон какая суровая, но было сильное желание отнести гаджет обратно в магазин. Просто потому, что он не стоит своих денег. Будь он тысяч на 5 дешевле, я бы взял и ни минуты об этом не жалел бы. Часть проблем, я уверен, решится с выходом новых прошивок. Остальные покроет более удачный софт, нежели тот, что предлагается изначально. Проблемы с USB подключением, с которыми я столкнулся, как мне кажется, вызваны работой под 64-битной версией ОС. Но какие аналоги есть? Почитав интернеты, сделал вывод, что заменить данный планшет нечем. Есть неплохая альтернатива среди планшетов от Acer &#8211; <strong>Acer Iconia Tab A501</strong>. Но в изяществе он значительно уступает Samsung Galaxy Tab 10.1, да и матрица там не так хорошая, а в экран Galaxy влюбляешься с первого взгляда в прямом смысле. Плюс очень сильно подкупает время работы Galaxy. Он действительно способен честно отработать до 10 часов при активном использовании.</p>
<p>В общем, если хотите хороший планшет, то покупайте <strong>Samsung Galaxy Tab 10.1</strong>, но только не сейчас. Подождите месяц-другой, когда он существенно упадет в цене, а это неизбежно случится, так как в начале следующего года на рынок поступит новое поколение планшетников, среди которых будет четырехядерный HTC и много других разных. Если очень хочется обзавестись устройством именно сейчас, то настоятельно рекомендую присмотреться к упомянутому Acer Iconia Tab A501. Отличная штука, но без лишних понтов и по адекватной цене. В принципе, изначально я на него и рассчитывал, но дернул черт посмотреть на продукт от Samsung&#8230;</p>
<p>Удачного вам выбора!</p>
<p><b>UPD 02.10.11:</b></p>
<p>История не закончилась. Я таки сделал то, о чем писал в конце данной заметки. Я отнес свой новый Galaxy Tab обратно в тот магазин, где его купил, благо, манибэк позволяет это сделать, не обосновывая свой поступок. На вопрос о том, что не так с купленным мною устройством, я ответил, что оно просто не стоит своих денег, и я был честен. Цена на Samsung Galaxy Tab 10.1 действительно завышена. В этом мнении я утвердился, когда увидел на яндекс маркете магазин, где данный гаджет стоит на 3000 рублей дешевле. Учитывая обилие недовольства от опыта общения с данным планшетом, я решил, что уж если и покупать его, то с максимальной экономией. Забрав свои деньги в одном магазине, я понес их в другой, где цена была более адекватной.</p>
<p>Не дураки придумали, что халявы не бывает. Магазин, который предлагал планшет по более низкой цене, продавал «серые» устройства. Собственно, спасибо продавцу-консультанту, который без лишних вопросов информировал меня о том, что устройство сертифицировано для Польши. Не могу сказать, что я брезгую «серым» товаром, но в данном конкретном случае это стало последней каплей. Для себя я понял, что на этом мое общение с Samsung Galaxy Tab 10.1 подошло к концу и пора прощаться. Но желание купить планшет никуда не делось и я пошел за другим девайсом, который также упоминал в данной заметке – это Acer Iconia Tab A501.</p>
<p>Продолжение истории я вынес в отдельную заметку. И так, кому интересно, <a href="/2011-10/review-acer-iconia-tab-a501.html">милости просим</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-09/review-samsung-galaxy-tab-10-1.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Bash скрипт создания виртуальных хостов Apache и Nginx</title>
		<link>http://inroot.ru/2011-08/bash-script-virtual-hosts-apache-nginx.html</link>
		<comments>http://inroot.ru/2011-08/bash-script-virtual-hosts-apache-nginx.html#comments</comments>
		<pubDate>Sat, 27 Aug 2011 07:56:34 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[bash скриптинг]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=675</guid>
		<description><![CDATA[Вчера опубликовал статью о своем опыте настройки VPS. Обещал, что как только появится время, напишу пару баш скриптов, которые автоматизируют часть рутинной работы и сведут количество действий, выполняемых руками, к разумному минимуму. Я напряг все имеющиеся извилины, откопал в аналах своей памяти скромные познания bash скриптинга и, потратив несколько часов, написал скромное приложение, которое упрощает [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2011/08/terminal_icon.png" alt="" title="" width="150" height="150" class="post_cover alignnone size-full wp-image-677" /></p>
<p>Вчера опубликовал статью о своем <a href="/2011-08/linux-server-apache-nginx-mysql-php-proftpd.html">опыте настройки VPS</a>. Обещал, что как только появится время, напишу пару баш скриптов, которые автоматизируют часть рутинной работы и сведут количество действий, выполняемых руками, к разумному минимуму.</p>
<p>Я напряг все имеющиеся извилины, откопал в аналах своей памяти скромные познания bash скриптинга и, потратив несколько часов, написал скромное приложение, которое упрощает и ускоряет процесс создания виртуальных хостов для Apache и Nginx.</p>
<p>Чтобы скрипт был хоть сколько-нибудь интересен не только мне и имел минимум привязки к среде, где он будет запускаться, я постарался вынести все пути и прочее в блок конфига, сохранив их в переменные. Тем не менее, я не рекомендую бездумно использовать его. Хотя бы глазами пробегитесь по коду, чтобы понимать, подойдет ли он вам «из коробки» (я сомневаюсь, если честно). Всякую ответственность за последствия, которые могут приключиться с вами после использования данного скрипта, само собой, я снимаю :) Все на свой страх и риск, как говорится. Но поломаться ничего не должно. Скрипт ничего не удаляет, не вносит изменений ни в какие файлы. Он может только намусорить…</p>
<p><span id="more-675"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Ниже код скрипта и некоторые комментарии к блоку конфига и способам использования.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;">####### CONFIG START  ########</span>
&nbsp;
<span style="color: #007800;">OWNER_NAME</span>=<span style="color: #ff0000;">'username'</span> <span style="color: #666666; font-style: italic;"># Пользователь, которому будет принадлежать директория вирт. хоста </span>
<span style="color: #007800;">OWNER_GROUP</span>=<span style="color: #ff0000;">'username'</span> <span style="color: #666666; font-style: italic;"># Группа, которой будет принадлежать директория вирт. хоста </span>
<span style="color: #007800;">HOME_WWW</span>=~username<span style="color: #000000; font-weight: bold;">/</span>www <span style="color: #666666; font-style: italic;"># Домашняя директория для вирт. хостов </span>
<span style="color: #007800;">HOST_DIRS</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">'backup'</span> <span style="color: #ff0000;">'logs'</span> <span style="color: #ff0000;">'public_html'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> 
<span style="color: #007800;">SERVER_IP</span>=<span style="color: #ff0000;">'127.0.0.1'</span> <span style="color: #666666; font-style: italic;"># IP адрес сервера</span>
&nbsp;
<span style="color: #007800;">WHEREIS_APACHE</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>apache2
<span style="color: #007800;">WHEREIS_NGINX</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>nginx
&nbsp;
<span style="color: #007800;">APACHE_HOSTS_DIR</span>=<span style="color: #007800;">$WHEREIS_APACHE</span><span style="color: #ff0000;">'/sites-available'</span>
<span style="color: #007800;">NGINX_HOSTS_DIR</span>=<span style="color: #007800;">$WHEREIS_NGINX</span><span style="color: #ff0000;">'/sites-available'</span>
<span style="color: #007800;">NGINX_HOSTS_ENABLED</span>=<span style="color: #007800;">$WHEREIS_NGINX</span><span style="color: #ff0000;">'/sites-enabled'</span>
&nbsp;
<span style="color: #666666; font-style: italic;">######## CONFIG END ##########</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># COLORS</span>
<span style="color: #007800;">SETCOLOR_SUCCESS</span>=<span style="color: #ff0000;">&quot;echo -en \\033[1;32m&quot;</span>
<span style="color: #007800;">SETCOLOR_FAILURE</span>=<span style="color: #ff0000;">&quot;echo -en \\033[1;31m&quot;</span>
<span style="color: #007800;">SETCOLOR_NORMAL</span>=<span style="color: #ff0000;">&quot;echo -en \\033[0;39m&quot;</span>
<span style="color: #007800;">SETCOLOR_NOTICE</span>=<span style="color: #ff0000;">&quot;echo -en \\033[1;33;40m&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># FUNCTIONS</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> restart_servers <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'Перезапускаем Apache'</span>
    <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>apache2 reload
&nbsp;
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'Перезапускаем Nginx'</span>
    <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>nginx reload
&nbsp;
    <span style="color: #7a0874; font-weight: bold;">return</span> <span style="color: #000000;">1</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> error_config <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #007800;">$SETCOLOR_FAILURE</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(tput hpa $(tput cols)</span>)<span style="color: #007800;">$(tput cub 6)</span>[Fail]&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'[CONFIG ERROR]: '</span><span style="color: #007800;">$1</span>
    <span style="color: #007800;">$SETCOLOR_NORMAL</span>
&nbsp;
    <span style="color: #7a0874; font-weight: bold;">exit</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> error_force_exec <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #007800;">$SETCOLOR_FAILURE</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(tput hpa $(tput cols)</span>)<span style="color: #007800;">$(tput cub 6)</span>[Fail]&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">'[FORCE EXEC ERROR]: '</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'Скрипт не может корректно выполнить все процедуры в автоматическом режиме'</span>
    <span style="color: #000000; font-weight: bold;">else</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$1</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
    <span style="color: #007800;">$SETCOLOR_NORMAL</span>
&nbsp;
    <span style="color: #7a0874; font-weight: bold;">exit</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> error_failure <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #007800;">$SETCOLOR_FAILURE</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(tput hpa $(tput cols)</span>)<span style="color: #007800;">$(tput cub 6)</span>[Fail]&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'[ERROR]: '</span><span style="color: #007800;">$1</span>
    <span style="color: #007800;">$SETCOLOR_NORMAL</span>
&nbsp;
    <span style="color: #7a0874; font-weight: bold;">exit</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> error_notice <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #007800;">$SETCOLOR_NOTICE</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'[NOTICE]: '</span><span style="color: #007800;">$1</span>
    <span style="color: #007800;">$SETCOLOR_NORMAL</span>
&nbsp;
    <span style="color: #7a0874; font-weight: bold;">return</span> <span style="color: #000000;">1</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Если запущен с ключем -f, значит задаем пользователю минимум вопросов </span>
<span style="color: #666666; font-style: italic;"># Игнорируются вопросы: </span>
<span style="color: #666666; font-style: italic;"># - имя директории виртуального хоста </span>
<span style="color: #666666; font-style: italic;"># - вопрос о перезапуске серверров (будут перезапущены)</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;$1&quot;</span> == <span style="color: #ff0000;">&quot;-f&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #007800;">force_execution</span>=<span style="color: #c20cb9; font-weight: bold;">true</span>
<span style="color: #000000; font-weight: bold;">else</span>
    <span style="color: #007800;">force_execution</span>=<span style="color: #c20cb9; font-weight: bold;">false</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span>
&nbsp;
<span style="color: #007800;">$SETCOLOR_NORMAL</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #007800;">$HOME_WWW</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #007800;">$HOME_WWW</span>
<span style="color: #000000; font-weight: bold;">else</span>
    error_config <span style="color: #ff0000;">&quot;Директория <span style="color: #007800;">$HOME_WWW</span> не существует&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Запрашивает имя домена, пока не будет введено</span>
<span style="color: #000000; font-weight: bold;">function</span> get_domain_name <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;Имя домена: &quot;</span>
    <span style="color: #c20cb9; font-weight: bold;">read</span> domain_name
&nbsp;
    <span style="color: #666666; font-style: italic;"># Если ничего не было введено</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #007800;">$domain_name</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #007800;">$SETCOLOR_FAILURE</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Вы не ввели имя домена&quot;</span>
	<span style="color: #007800;">$SETCOLOR_NORMAL</span>
	get_domain_name
    <span style="color: #000000; font-weight: bold;">else</span>
	<span style="color: #7a0874; font-weight: bold;">return</span> <span style="color: #000000;">1</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Запрашивает имя директории для виртуального хоста или предлагает создать автоматически </span>
<span style="color: #666666; font-style: italic;"># проверяет его на существование</span>
<span style="color: #000000; font-weight: bold;">function</span> get_host_dir <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;Имя директории хоста: &quot;</span>
    <span style="color: #c20cb9; font-weight: bold;">read</span> host_dir
&nbsp;
    <span style="color: #666666; font-style: italic;"># Если ничего не было введено</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #007800;">$host_dir</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #007800;">$SETCOLOR_NOTICE</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;Вы не ввели имя директории хоста. Создать автоматически? [Н/д]? &quot;</span>
	<span style="color: #007800;">$SETCOLOR_NORMAL</span>
&nbsp;
	<span style="color: #c20cb9; font-weight: bold;">read</span> answer
&nbsp;
	    <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$answer</span>&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
	    Y<span style="color: #000000; font-weight: bold;">|</span>y<span style="color: #000000; font-weight: bold;">|</span>д<span style="color: #000000; font-weight: bold;">|</span>Д<span style="color: #7a0874; font-weight: bold;">&#41;</span>
		<span style="color: #007800;">host_dir</span>=<span style="color: #800000;">${domain_name//\./_}</span>
		<span style="color: #007800;">host_dir</span>=<span style="color: #800000;">${host_dir//\-/}</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #800000;">${HOME_WWW}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${host_dir}</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
		    error_notice <span style="color: #ff0000;">&quot;Автоматический выбор имени директории невозможен. Задайте его самостоятельно&quot;</span>
		    get_host_dir
		<span style="color: #000000; font-weight: bold;">else</span>
		    error_notice <span style="color: #ff0000;">&quot;Директория хоста будет создана автоматически: <span style="color: #007800;">$host_dir</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">fi</span>
		<span style="color: #7a0874; font-weight: bold;">return</span> <span style="color: #000000;">1</span>
		<span style="color: #000000; font-weight: bold;">;;</span>
	    N<span style="color: #000000; font-weight: bold;">|</span>n<span style="color: #000000; font-weight: bold;">|</span>о<span style="color: #000000; font-weight: bold;">|</span>О<span style="color: #7a0874; font-weight: bold;">&#41;</span> get_host_dir
		<span style="color: #000000; font-weight: bold;">;;</span>
	    <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> get_host_dir
		<span style="color: #000000; font-weight: bold;">;;</span>
	    <span style="color: #000000; font-weight: bold;">esac</span>
	get_host_dir
    <span style="color: #000000; font-weight: bold;">else</span>
	<span style="color: #7a0874; font-weight: bold;">return</span> <span style="color: #000000;">1</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
get_domain_name
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #007800;">$force_execution</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #007800;">host_dir</span>=<span style="color: #800000;">${domain_name//\./_}</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #800000;">${HOME_WWW}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${host_dir}</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	error_force_exec
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">else</span>
    get_host_dir
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Проверяем пути апача из конфига</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #007800;">$APACHE_HOSTS_DIR</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$APACHE_HOSTS_DIR</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$domain_name</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	error_failure <span style="color: #ff0000;">&quot;Виртуальный хост <span style="color: #007800;">$domain_name</span> уже существует для Apache&quot;</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">else</span>
    error_config <span style="color: #ff0000;">&quot;Директория <span style="color: #007800;">$APACHE_HOSTS_DIR</span> не существует&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Проверяем пути nginx из конфига</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #007800;">$NGINX_HOSTS_DIR</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$NGINX_HOSTS_DIR</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$domain_name</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        error_failure <span style="color: #ff0000;">&quot;Виртуальный хост <span style="color: #007800;">$domain_name</span> уже существует Nginx&quot;</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">else</span>
    error_config <span style="color: #ff0000;">&quot;Директория <span style="color: #007800;">$NGINX_HOSTS_DIR</span> не существует&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Домен: <span style="color: #007800;">$domain_name</span>&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Создаем директории виртуального хоста</span>
<span style="color: #007800;">host_dir_path</span>=<span style="color: #800000;">${HOME_WWW}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${host_dir}</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Создаем директории виртуального хоста:&quot;</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #007800;">$host_dir_path</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> dir_name <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #800000;">${HOST_DIRS[@]}</span>; <span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #007800;">$host_dir_path</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$dir_name</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span> <span style="color: #007800;">$host_dir_path</span>/<span style="color: #007800;">$dir_name</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">touch</span> <span style="color: #800000;">${host_dir_path}</span><span style="color: #ff0000;">'/public_html/index.html'</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Рекурсивно проставляем права</span>
<span style="color: #c20cb9; font-weight: bold;">chown</span> <span style="color: #660033;">-R</span> <span style="color: #007800;">$OWNER_NAME</span>:<span style="color: #007800;">$OWNER_GROUP</span> <span style="color: #007800;">$host_dir_path</span>
&nbsp;
<span style="color: #007800;">apache_template</span>=<span style="color: #ff0000;">&quot;&lt;VirtualHost 127.0.0.1:8080&gt;
      ServerAdmin webmaster@<span style="color: #007800;">$domain_name</span>
      ServerName <span style="color: #007800;">$domain_name</span>
      ServerAlias www.<span style="color: #007800;">$domain_name</span>
      DocumentRoot <span style="color: #007800;">$HOME_WWW</span>/<span style="color: #007800;">$host_dir</span>/public_html
&nbsp;
      ScriptAlias /cgi-bin/ <span style="color: #007800;">$HOME_WWW</span>/<span style="color: #007800;">$host_dir</span>/public_html/cgi-bin/
      ErrorLog <span style="color: #007800;">$HOME_WWW</span>/<span style="color: #007800;">$host_dir</span>/logs/apache.error.log
      LogLevel warn
      CustomLog <span style="color: #007800;">$HOME_WWW</span>/<span style="color: #007800;">$host_dir</span>/logs/apache.access.log combined
&lt;/VirtualHost&gt;&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Создаем конфиг виртуального хоста apache</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'Создаем конфиг виртуального хоста apache:'</span>
<span style="color: #c20cb9; font-weight: bold;">touch</span> <span style="color: #800000;">${APACHE_HOSTS_DIR}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${domain_name}</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #800000;">${APACHE_HOSTS_DIR}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${domain_name}</span>
&nbsp;
<span style="color: #007800;">temp_ifs</span>=<span style="color: #007800;">$IFS</span>
<span style="color: #007800;">IFS</span>=
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$apache_template</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #800000;">${APACHE_HOSTS_DIR}</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$domain_name</span>
<span style="color: #007800;">IFS</span>=<span style="color: #007800;">$temp_ifs</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># создаем симлинк</span>
a2ensite <span style="color: #007800;">$domain_name</span>
&nbsp;
<span style="color: #007800;">nginx_template</span>=<span style="color: #ff0000;">&quot;server {
      listen <span style="color: #007800;">$SERVER_IP</span>:80;
&nbsp;
      server_name <span style="color: #007800;">$domain_name</span> www.<span style="color: #007800;">$domain_name</span>;
      access_log  <span style="color: #007800;">$HOME_WWW</span>/<span style="color: #007800;">$host_dir</span>/logs/nginx.access.log;
&nbsp;
      location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar)$ {
            root /home/omm/www/<span style="color: #007800;">$host_dir</span>/public_html;
      }
&nbsp;
&nbsp;
      location / {
            proxy_pass http://backend;
            proxy_redirect off;
            proxy_set_header Host <span style="color: #000099; font-weight: bold;">\$</span>host;
            proxy_set_header X-Real-IP <span style="color: #000099; font-weight: bold;">\$</span>remote_addr;
&nbsp;
            charset utf-8;
            index index.html;
            root <span style="color: #007800;">$HOME_WWW</span>/<span style="color: #007800;">$host_dir</span>/public_html;
      }
}&quot;</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;"># Создаем конфиг виртуального хоста nginx</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'Создаем конфиг виртуального хоста nginx:'</span>
<span style="color: #c20cb9; font-weight: bold;">touch</span> <span style="color: #800000;">${NGINX_HOSTS_DIR}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${domain_name}</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #800000;">${NGINX_HOSTS_DIR}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${domain_name}</span>
&nbsp;
<span style="color: #007800;">temp_ifs</span>=<span style="color: #007800;">$IFS</span>
<span style="color: #007800;">IFS</span>=
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$nginx_template</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #800000;">${NGINX_HOSTS_DIR}</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$domain_name</span>
<span style="color: #007800;">IFS</span>=<span style="color: #007800;">$temp_ifs</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># создаем симлинк</span>
<span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #007800;">$NGINX_HOSTS_DIR</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$domain_name</span> <span style="color: #007800;">$NGINX_HOSTS_ENABLED</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$domain_name</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Перезапускаем сервера</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #007800;">$force_execution</span>; <span style="color: #000000; font-weight: bold;">then</span>
    restart_servers
<span style="color: #000000; font-weight: bold;">else</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">'Перезапустить Apache и Nginx? [Д/н] '</span>
    <span style="color: #c20cb9; font-weight: bold;">read</span> restart_answer
&nbsp;
    <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$restart_answer</span>&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
	Y<span style="color: #000000; font-weight: bold;">|</span>y<span style="color: #000000; font-weight: bold;">|</span>д<span style="color: #000000; font-weight: bold;">|</span>Д<span style="color: #7a0874; font-weight: bold;">&#41;</span>
	    restart_servers
	<span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
	    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'Apache и Nginx не были перезагружены'</span>
	<span style="color: #000000; font-weight: bold;">;;</span>
    <span style="color: #000000; font-weight: bold;">esac</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #007800;">$SETCOLOR_SUCCESS</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(tput hpa $(tput cols)</span>)<span style="color: #007800;">$(tput cub 6)</span>[OK]&quot;</span>
<span style="color: #007800;">$SETCOLOR_NORMAL</span></pre></td></tr></table></div>

<h2>Конфигурирование скрипта</h2>
<p>В скрипте есть комментарии, но опишу переменные настройки еще раз.</p>
<p><strong>OWNER_NAME</strong> – имя системного пользователя, которому будут принаджелать директории и файлы, создаваемые скриптом для виртуального хоста.</p>
<p><strong>OWNER_GROUP</strong> – системная группа, которой будут принаджелать директории и файлы, создаваемые скриптом для виртуального хоста.</p>
<p><strong>HOME_WWW</strong> – внутри этой директории будет создана директория виртуального хоста.</p>
<p><strong>HOST_DIRS</strong> – директории виртуального хоста, которые будут созданы. По-умолчанию сюда вписана директория для логов apache и nginx, директория для бэкапов и директория, которая будет доступна по http протоколу, собственно, куда и нужно будет класть все файлы вашего сайта.</p>
<p><strong>SERVER_IP</strong> – ip адрес вашего сервера. Прописывается в конфигах nginx.</p>
<p><strong>WHEREIS_APACHE</strong> – директория установки Apache. Относительно нее будут искаться конфиги виртуальных хостов и прочее.</p>
<p><strong>WHEREIS_NGINX</strong> &#8211; директория установки Nginx. Относительно нее будут искаться конфиги виртуальных хостов и прочее.</p>
<p><strong>APACHE_HOSTS_DIR</strong> – директория, где Apache хранит конфиги для каждого отдельного виртуального хоста. Обычно это sites-available.</p>
<p><strong>NGINX_HOSTS_DIR</strong> &#8211; директория, где Nginx хранит конфиги для каждого отдельного виртуального хоста. Обычно это sites-available.</p>
<p><strong>NGINX_HOSTS_ENABLED</strong> – директория, где хранятся симлинки на конфиги виртуального хоста Nginx. В nginx нет утилиты подобной a2ensite, поэтому нужно знать, куда создать ссылку самим. Обычно данная директория называется sites-enabled.</p>
<p>Есть еще несколько переменных, в которых хранится код разукраски сообщений, которыми скрипт отписывается в консоль. Также можно поправить поведение ряда функци. Но все это совсем опционально и если очень хочется, то поглядите сами. Там все просто.</p>
<p>В скрипте есть еще две переменных, которые объявлены почти в конце листинга: apache_template и nginx_template. В них хранятся шаблоны для виртуальных хостов. Хотя бы посмотрите, что в них описано, чтобы быть уверенными в том, что конфиги имеют именно тот вид, который вам требуется.</p>
<h2>Работа со скриптом</h2>
<p>Скрипт может работать в двух режимах.</p>
<p><strong>Простой запуск</strong> – запускаете скрипт и отвечаете на его вопросы. Он потребует ввести:</p>
<ul>
<li>имя домена, для которого создаются конфиги;</li>
<li>имя директории виртуального хоста;</li>
<li>спросит перезагрузить ли сервера, после того, как конфиги будут созданы</li>
</ul>
<p>Если не задать скрипту имя директории виртуального хоста, то он создает ее автоматически. От перезагрузки серверов можно отказаться. Это удобно, когда вы планируете создать несколько виртуальных хостов подряд и нет смысла каждый раз заставлять Nginx и Apache делать reload (при reload создается избыточная нагрузка на процессор и потребляется больше памяти. Лучше сделать это один раз, когда все хосты будут добавлены).</p>
<p><strong>Форсированный запуск</strong> – это типа автоматического режима. Скрипт задает только один вопрос – о имени домена. Все остальное он делает сам, в том числе перезагружает Nginx и Apache. При этом, если в ходе проверок скрипт выяснит, что выполнить какие-то операции он не сможет, то работа прекратится. Но учтите, что никаких подробных сообщений о проблеме не будет. Скрипт просто скажет, что он не может отработать в автоматическом режиме (скорее всего, конфликты с путями). </p>
<p>Для вызова скрипта в форсированом режиме необходимо запустить его с параметром –f</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">bash</span> script_name.sh <span style="color: #660033;">-f</span></pre></div></div>

<p>На баше я пишу раз в сотню лет, так что, уж не обессудьте.</p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-08/bash-script-virtual-hosts-apache-nginx.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Сборка сервера Apache + Nginx + MySQL + PHP + ProFTPD</title>
		<link>http://inroot.ru/2011-08/linux-server-apache-nginx-mysql-php-proftpd.html</link>
		<comments>http://inroot.ru/2011-08/linux-server-apache-nginx-mysql-php-proftpd.html#comments</comments>
		<pubDate>Fri, 26 Aug 2011 21:39:11 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Nxing]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ProFTPD]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=646</guid>
		<description><![CDATA[Как ни странно, несмотря на развитость рынка хостинга и обилие предложений VPS, многие все еще сидят на виртуальных хостингах. Я не исключение. Раньше меня останавливали ценники на услуги dedecated или colocation. Потом эти услуги значительно упали в цене и появились еще более дешевые – VPS. Но меня все равно останавливали неведомые силы и я продолжал [...]]]></description>
			<content:encoded><![CDATA[<p>Как ни странно, несмотря на развитость рынка хостинга и обилие предложений VPS, многие все еще сидят на виртуальных хостингах. Я не исключение. Раньше меня останавливали ценники на услуги dedecated или colocation. Потом эти услуги значительно упали в цене и появились еще более дешевые – VPS. Но меня все равно останавливали неведомые силы и я продолжал ютиться на виртуалке. Наверное, просто не было веских причин для смены площадки. Я вообще очень консервативен в таких вопросах.</p>
<p>Но пришел момент, когда меня утомило то, что сайты разбросаны по разным аккаунтам и разным хостингам. Захотелось иметь возможность использовать сервера кэширования, сервер баз данных последней стабильной версии, а также несколько библиотек для PHP и Python, которых нет на виртуалках. Не могу сказать, что всего этого хотел очень сильно, но мотивация появилась и я решил съехать на VPS.</p>
<p>Сразу скажу, что я никогда не администрировал сервера сколько-нибудь серьезно. Я вообще их не администрировал, не считая смешного опыта где-то там, на заре своей карьеры. Уровень познания Linux можно назвать «слабенький пользователь». То есть, если оставить меня один на один с linux’ом, я не впаду в панику и таки добьюсь того, что требуется, но проведу долбанную кучу времени за чтением манов.</p>
<p><span id="more-646"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>И так, учитывая уровень моих познаний, вы можете сделать вывод – читать дальше или нет. Писал исключительно для тех, кто настолько же просвещен, как я. Остальным будет не интересно или даже вредно для здоровья.</p>
<p>Насколько я прав в своей статья, я не знаю. Но то, что я собрал – работает и меня это радует. Значит можно будет двигаться дальше. Если вас такой расклад устраивает, то милости прошу к прочтению.</p>
<p>Также замечу, что собирать я буду некоторое подобие виртуального хостинга. То есть на VPS будет ютиться n-ое количество сайтов, с возможностью заведения FTP, например, для каких-нибудь посторонних людей. Про посторонних людей, я немного погорячился, наверное, так как и апач и nginx всегда будут запускаться от одного пользователя. Но это можно будет поправить патчами.</p>
<h2>Сборка сервера Apache + Nginx + MySQL + PHP + ProFTPD</h2>
<p>И так, в качестве ОС я выбрал Debian, как достаточно популярный, как мне кажется, дистрибутив и, что немаловажно, наиболее простой для меня. В Debian все ставится из репозитария, где лежат стабильные версии, хотя порой несколько устаревшие. К слову, сначала я попробовал собрать весь комплект из исходников и даже собрал. Но потом случился какой-то затык, уже не помню с чем и я на своем опыте убедился, что сбор из исходников это не «Debian way». Забросил эту идею и все переделал по уму.</p>
<p>VPS я взял у <a href="http://clodo.ru/r5091" target="_blank" rel="external nofollow">Clodo</a>. Есть недельный Moneyback. Недели тестового периода как раз хватит для того, чтобы понять, что получается из всей этой затеи и стоит ли продолжать. Ценник меня тоже вполне устроил:  512 памяти и 10гб HDD обойдутся в туже сумму, что мне сейчас обходится два аккаунта на виртуальном хостинге. То есть, с финансовой точки зрения, я даже сэкономлю рублей 200, если перенесу все сайты на VPS. Сумасшедшая сумма, конечно.</p>
<p>Версия Debian 6-64 bits. Все остальное, как я уже говорил, ставил из репозитариев, поэтому с версиями особо не напрягался.</p>
<p>Вся установка ведется от <tt>root</tt> пользователя и на совершенно чистую систему.</p>
<h2>Устанавливаем Apache 2</h2>
<p>Сначала просто поставим Apache. Настройку и конфигурирование оставим на потом.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> apache2</pre></div></div>

<p>Если все установилось нормально, то обратившись по ip адресу сервера, мы увидим страницы приветствия Apache.</p>
<h2>Установка Nginx</h2>
<p>На текущий момент, в репозитарии Debian лежит версия 0.7.67. Старова-то, конечно, но ничего не поделаешь. В Backports лежит тоже самое, а собирать из исходников я не стал. Как можно убедиться из многочисленных обсуждений на форумах, это не &#8220;Debian way&#8221;. Можно было бы попробовать собрать свой deb пакет, но что-то я пока морально не готов к этому. В общем, ставим из репозитария то, что предлагают.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> nginx</pre></div></div>

<h2>Устанавливаем MySQL сервер</h2>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> mysql-server</pre></div></div>

<p>Конфигурировать пока тоже ничего не будем. Единственное, что потребуется – задать пароль для root пользователя. Не оставляйте пароль пустой строкой.</p>
<h2>Устанавливаем PHP</h2>
<p>Перед тем, как приступить к установке, можете проверить, какая версия PHP присутствует в репозитарии. Это можно сделать командой</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-cache</span> policy php5</pre></div></div>

<p>Если вас все устраивает, то ставим</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> php5 php-pear
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> php5-mysql <span style="color: #666666; font-style: italic;"># ставим пакет для работы php с mysql</span>
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> php5-suhosin <span style="color: #666666; font-style: italic;"># патчим php, повышая его безопасность, хотя он мог установиться сразу с php</span></pre></div></div>

<h2>Небольшая настройка</h2>
<p>Еще немного ПО для удобства работы. Я поставил Midnight Commander, чтобы было удобнее осуществлять навигацию по файловой системе.<br />
Теперь приступаем к настройке всего, что поставили.</p>
<p>Мне нравится, когда файлы всех виртуальных хостов лежат в поддиректориях домашней директории какого-нибудь пользователя. Привычка такая, наверное. Плюс можно будет сделать скрипт, который автоматизирует процесс создания виртуальных хостов, если их у вас будет много. Если вас не смущает такая политика, то предлагаю добавить в систему пользователя и задать ему пароль:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">useradd omm <span style="color: #660033;">-d</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>omm <span style="color: #660033;">-m</span> <span style="color: #666666; font-style: italic;"># omm замените на желаемое вами имя пользователя, но у меня оно такое</span>
<span style="color: #c20cb9; font-weight: bold;">passwd</span> omm</pre></div></div>

<p>Ключ –d задает путь к домашней директории пользователя, а -m говорит о том, что эту директорию нужно создать.<br />
Все пути, связанные с домашней директорией пользователя, я буду указывать с учетом имени omm, вам же следует подставлять имя своего пользователя.<br />
Виртуальные хосты я буду складывать в /home/omm/www.  Туда же будут ходить отдельные FTP пользователи, каждый в свою поддиректорию внутри www.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>omm<span style="color: #000000; font-weight: bold;">/</span>www <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">chown</span> <span style="color: #660033;">-R</span> omm:omm <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>omm</pre></div></div>

<p>Если хотите другую версию PHP, то можно поискать репозитарии, в которых она есть, добавить их и ставить оттуда.</p>
<h2>Установка FTP сервера ProFTPD </h2>
<p>Я также хочу поднять FTP сервер. Почитал несколько разных статей и решил, что поставлю Proftpd. Замечу, что во время установки лучше выбрать режим standalone (не лучше, но диктуется обстоятельствами), так как в Debian нет демона inеtd (есть xinetd).</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> proftpd</pre></div></div>

<p>Теперь нужно конфигурировать FTP сервер. Для этого открываем в редакторе файл /etc/proftpd/proftpd.conf<br />
Расскомментируем директиву DefaultRoot и меняем ее значение. Также снимаем комментарий с директивы RequireValidShell.</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">DefaultRoot                     /home/omm/www #выше этой директории ни один пользователь не поднимется</pre></div></div>

<p>Если у вас таки будет полноценный виртуальный хостинг, то лучше оставить значение по-умолчанию. Тогда для каждого пользователя домашней директорией будет его домашняя директория.</p>
<p>Где-нибудь после директивы DeferWelcome добавялем</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">RootLogin                       off</pre></div></div>

<p>Это запретит подключение по FTP под учетной записью root.</p>
<p>Также добавим ведение еще одного лога, у которого будет понятный для чтения формат. Для этого, после директивы SystemLog пишем:</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">LogFormat custom &quot;%t [pid %P] [%u] ip: %a %m %f [%b b for %T seconds]&quot;
ExtendedLog /var/log/proftpd/transfer.log</pre></div></div>

<p>Я обычно увеличиваю таймауты на простой FTP соединения. Но это по вкусу. Сохраняем изменения.</p>
<p>В конец конфига добавляем строку</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">Include /etc/proftpd/rules/*</pre></div></div>

<p>Следом создаем эту директорию и первый файл конфига в ней</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">mkdir /etc/proftpd/rules &amp;&amp; touch /etc/proftpd/rules/omm</pre></div></div>

<p>Открываем файл omm и пишем туда конфиг, который позволит пользователю omm видеть/изменять все, что в этой директории и ниже. То есть, у нас получается что-то типа главного ftp пользователя. Это удобно, но не очень безопасно. Если у вас сопрут пароль от этого пользователя, то смогут одним махом побить файлы на всех сайтах.</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">&lt;directory /home/omm/www&gt;
        &lt;limit READ WRITE DIRS&gt;
                 Order allow,deny
                 AllowUser omm
                 DenyAll
         &lt;/limit&gt;
&lt;/directory&gt;</pre></div></div>

<p>Проверяем файл конфига на наличие ошибок и если все хорошо, перезапускаем ftp сервер.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">proftpd <span style="color: #660033;">-td5</span>
<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>proftpd restart</pre></div></div>

<p>Если ошибок в файле конфига допущено не было, то сервер перезагрузится в штатном режиме. Осталось только открыть ваш FTP клиент и проверить, все ли работает.</p>
<p>Не охота забегать вперед, но все же напишу немного о том, как создавать виртуальных ftp пользователей.</p>
<p>Сначала создадим директорию внутри нашей www, которая якобы будет корневой директорией для одного из сайтов</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">mkdir</span> ~omm<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>test_ru</pre></div></div>

<p>Создаем виртуального FTP пользователя testru и указываем созданную директорию как его домашнюю. Используем утилиту ftpasswd c необходимыми параметрами:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ftpasswd <span style="color: #660033;">--passwd</span> <span style="color: #660033;">--file</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>proftpd<span style="color: #000000; font-weight: bold;">/</span>ftpd.passwd <span style="color: #660033;">--name</span>=testru <span style="color: #660033;">--shell</span>=<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">false</span> <span style="color: #660033;">--home</span>=<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>omm<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>test_ru <span style="color: #660033;">--uid</span>=<span style="color: #000000;">1001</span> <span style="color: #660033;">--gid</span>=<span style="color: #000000;">1002</span>
ftpasswd <span style="color: #660033;">--group</span> <span style="color: #660033;">--file</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>proftpd<span style="color: #000000; font-weight: bold;">/</span>ftpd.group <span style="color: #660033;">--name</span>=proudprods <span style="color: #660033;">-m</span> testru <span style="color: #660033;">-gid</span>=<span style="color: #000000;">1002</span>
<span style="color: #c20cb9; font-weight: bold;">chmod</span> <span style="color: #000000;">644</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>proftpd<span style="color: #000000; font-weight: bold;">/</span>ftpd.passwd <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>proftpd<span style="color: #000000; font-weight: bold;">/</span>ftpd.group
<span style="color: #c20cb9; font-weight: bold;">chown</span> proftpd:nogroup <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>proftpd<span style="color: #000000; font-weight: bold;">/</span>ftpd.passwd <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>proftpd<span style="color: #000000; font-weight: bold;">/</span>ftpd.group</pre></div></div>

<p>Обратите внимание на uid и gid. Я указал id своего пользователя omm и его группы, так как все файлы будут лежать ниже его домашней директории.</p>
<p>Теперь снова открываем конфиг /etc/proftpd/proftpd.conf и добавляем еще две директивы. Как нетрудно догадаться, они указывают пути для файлов с данными виртуальных пользователей и групп.</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">AuthUserFile                    /etc/proftpd/ftpd.passwd
AuthGroupFile                   /etc/proftpd/ftpd.group</pre></div></div>

<p>Делаем рестарт сервера и пробуем залогиниться под созданным виртуальным пользователем. Должно все работать правильно.</p>
<p>Чтобы теперь добавить нового виртуального пользователя используем туже команду, что и раньше, только без параметра &#8211;file, например:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ftpasswd <span style="color: #660033;">--passwd</span> <span style="color: #660033;">--name</span> testru <span style="color: #660033;">--home</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>omm<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>test_ru <span style="color: #660033;">--shell</span>=<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">false</span> <span style="color: #660033;">--uid</span>=<span style="color: #000000;">1001</span> <span style="color: #660033;">--gid</span>=<span style="color: #000000;">1002</span></pre></div></div>

<h2>Настройка Apache</h2>
<p>Открываем /etc/apache2/ports.conf и в значении директивы NameVirtualHost звездочку заменяем на 127.0.0.1:8080, тоже самое пишем для директивы Listen:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">NameVirtualHost</span> 127.0.0.1:<span style="color: #ff0000;">8080</span>
<span style="color: #00007f;">Listen</span> 127.0.0.1:<span style="color: #ff0000;">8080</span></pre></div></div>

<p>Мы перевесили Apache на порт 8080 и сделали его недоступным напрямую. Рестартим Apache и смотрим поцепился ли он на 127.0.0.1:8080</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>apache2 restart <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">netstat</span> <span style="color: #660033;">-anp</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> LISTEN <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> apache2</pre></div></div>

<p>Теперь нужно создать конфиги виртуальных хостов для каждого вашего домена или поддомена. Скажу лишь только то, что для каждого хоста нужно создавать отдельный конфиг в директории /etc/apache2/sites-available</p>
<p>Там уже есть два конфига, на примере которых вы можете создать свои. Я не стану описывать синтаксис, так как ничего сложного там нет. Приведу лишь подправленный мною default, который я переписал на работу с /home/omm/www/test_ru. Имя хоста не прописывал ввиду того, что у меня пока нет доменов, привязанных к настраиваемому VPS, следовательно тестить буду по IP адресу сервера.</p>
<p>Содержимое /etc/apache2/sites-available/default</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;">&lt;<span style="color: #000000; font-weight:bold;">VirtualHost</span> 127.0.0.1:<span style="color: #ff0000;">8080</span>&gt;
        <span style="color: #00007f;">ServerAdmin</span> webmaster@localhost
&nbsp;
        <span style="color: #00007f;">DocumentRoot</span> /home/omm/www/test_ru/
        &lt;<span style="color: #000000; font-weight:bold;">Directory</span> /&gt;
                <span style="color: #00007f;">Options</span> <span style="color: #0000ff;">FollowSymLinks</span>
                <span style="color: #00007f;">AllowOverride</span> <span style="color: #0000ff;">None</span>
        &lt;/<span style="color: #000000; font-weight:bold;">Directory</span>&gt;
        &lt;<span style="color: #000000; font-weight:bold;">Directory</span> /home/omm/www/test_ru&gt;
                <span style="color: #00007f;">Options</span> <span style="color: #0000ff;">Indexes</span> <span style="color: #0000ff;">FollowSymLinks</span> MultiViews
                <span style="color: #00007f;">AllowOverride</span> <span style="color: #0000ff;">None</span>
                <span style="color: #00007f;">Order</span> <span style="color: #00007f;">allow</span>,<span style="color: #00007f;">deny</span>
                <span style="color: #00007f;">allow</span> from <span style="color: #0000ff;">all</span>
        &lt;/<span style="color: #000000; font-weight:bold;">Directory</span>&gt;
&nbsp;
        <span style="color: #00007f;">ScriptAlias</span> /cgi-bin/ /usr/lib/cgi-bin/
        &lt;<span style="color: #000000; font-weight:bold;">Directory</span> <span style="color: #7f007f;">&quot;/usr/lib/cgi-bin&quot;</span>&gt;
                <span style="color: #00007f;">AllowOverride</span> <span style="color: #0000ff;">None</span>
                <span style="color: #00007f;">Options</span> +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                <span style="color: #00007f;">Order</span> <span style="color: #00007f;">allow</span>,<span style="color: #00007f;">deny</span>
                <span style="color: #00007f;">Allow</span> from <span style="color: #0000ff;">all</span>
        &lt;/<span style="color: #000000; font-weight:bold;">Directory</span>&gt;
&nbsp;
        <span style="color: #00007f;">ErrorLog</span> ${APACHE_LOG_DIR}/error.log
&nbsp;
        <span style="color: #adadad; font-style: italic;"># Possible values include: debug, info, notice, warn, error, crit,</span>
        <span style="color: #adadad; font-style: italic;"># alert, emerg.</span>
        <span style="color: #00007f;">LogLevel</span> warn
&nbsp;
        <span style="color: #00007f;">CustomLog</span> ${APACHE_LOG_DIR}/access.log combined
&nbsp;
    <span style="color: #00007f;">Alias</span> /doc/ <span style="color: #7f007f;">&quot;/usr/share/doc/&quot;</span>
    &lt;<span style="color: #000000; font-weight:bold;">Directory</span> <span style="color: #7f007f;">&quot;/usr/share/doc/&quot;</span>&gt;
        <span style="color: #00007f;">Options</span> <span style="color: #0000ff;">Indexes</span> MultiViews <span style="color: #0000ff;">FollowSymLinks</span>
        <span style="color: #00007f;">AllowOverride</span> <span style="color: #0000ff;">None</span>
        <span style="color: #00007f;">Order</span> <span style="color: #00007f;">deny</span>,<span style="color: #00007f;">allow</span>
        <span style="color: #00007f;">Deny</span> from <span style="color: #0000ff;">all</span>
        <span style="color: #00007f;">Allow</span> from 127.0.0.0/255.0.0.0 ::<span style="color: #ff0000;">1</span>/<span style="color: #ff0000;">128</span>
    &lt;/<span style="color: #000000; font-weight:bold;">Directory</span>&gt;
&nbsp;
&lt;/<span style="color: #000000; font-weight:bold;">VirtualHost</span>&gt;</pre></div></div>

<p>Директории, которые указаны в конфиге виртуального хоста должны существовать. Если все сделали, выполняем команду</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">a2ensite default <span style="color: #666666; font-style: italic;"># default – имя файла конфига</span></pre></div></div>

<p>Выполнение данной команды создаст ссылку на файл конфига в директории sites-enabled.</p>
<p>Перечитываем конфиги apache</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>apache2 reload</pre></div></div>

<p>Создаем файл и пишем в него что-нибудь</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">touch</span> ~omm<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>test_ru<span style="color: #000000; font-weight: bold;">/</span>index.html <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">nano</span> ~omm<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>test_ru<span style="color: #000000; font-weight: bold;">/</span>index.html</pre></div></div>

<p>Теперь обращаемся к вашему серверу по IP адресу и если видим строку, которую вписали в файл index.html, то радуемся. Если не видим, то расстраиваемся и думаем, где накосячили.</p>
<h2>Настройка Nginx</h2>
<p>Теперь можно запустить Nginx. Если он нормально поцепился на 80 порт, то при обращении к серверу по ip мы должны увидеть страницу приветствия Nginx.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>nginx start</pre></div></div>

<p>Открываем конфиг /etc/nginx/nginx.conf и в секцию http, перед  директивами include, описываепроксирующий сервер с помощью модуля <a href="http://sysoev.ru/nginx/docs/http/ngx_http_upstream.html" target="_blank" rel="external nofollow">upstream</a></p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;">http {
    <span style="color: #adadad; font-style: italic;"># …</span>
    upstream backend {
        server 127.0.0.1:<span style="color: #ff0000;">8080</span>;
    }
&nbsp;
    <span style="color: #00007f;">include</span> /etc/nginx/conf.d/*.conf;
    <span style="color: #00007f;">include</span> /etc/nginx/sites-enabled/*;
}</pre></div></div>

<p>Теперь открываем конфиг /etc/nginx/sites-available/default и приводим его к следующему виду</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;">server {
         <span style="color: #00007f;">listen</span> <span style="color: #ff0000;">80</span>;
         server_name localhost;
&nbsp;
         location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar)$ {
                root /home/omm/www/test_ru;
         }
&nbsp;
         location / {
                proxy_pass http://backend;
                proxy_redirect <span style="color: #0000ff;">off</span>;
                proxy_set_header Host   $host;
                proxy_set_header X-Real-IP      $remote_addr;
&nbsp;
                charset utf-<span style="color: #ff0000;">8</span>;
                index test.php index.html;
                root /home/omm/www/ test_ru;
         }
 }</pre></div></div>

<p>Перезапускаем сервер. Пробуем запрашивать статику и скрипты. Смотрим access логи apache и nginx, по которым будет видно, какие запросы и куда уходят.</p>
<p>Теперь статика будет отдаваться через nginx, а все остальное уйдет на проксирующий apache.</p>
<h2>Настрайка MySQL</h2>
<p>Запускаем mysql_secure_installation и следуем всем инструкциям и отвечаем на все вопросы, которые нам зададут.</p>
<p>Так как пароль для root мы уже задали при установке, то сейчас потребуется его ввести и на следующий вопрос о смене пароля можно ответить «нет»<br />
На все последующие вопросы отвечаем утвердительно. Это максимально правильно и безопасно. В описание к фонфигуратору говорится, что они только для тестовых запусков сервера и никак не для продакшена.</p>
<p>На этом настройка окончена :)</p>
<h2>Настройка PHP</h2>
<p>Настраивать, на самом деле, нечего. PHP и так уже работает. Вы можете поковырять /etc/php5/apache2/php.ini, если знаете, что там и к чему. Если не знаете, очень советую узнать.<br />
Не забывайте, что после изменений в php.ini, нужно перезапускать апач, чтобы они вступили в силу.</p>
<p>Пока можете потестировать работу PHP с MySQL, например.</p>
<h2>В заключении</h2>
<p>Файлы, которые мы создавали в директории ~omm/www/test_ru/ нужно удалить от root пользователя, так как мы от него их и создавали (во всяком случае, я создавал от root) и по FTP они доступны только для чтения.</p>
<p>Теперь весь этот огород осталось настроить для оптимальной работы. Отключить не нужное, правильно сконфигурировать необходимое, установить по, которого не хватает, но очень хочется, например Memcached и eAccelerator. Не забывайте, что это VPS, а не виртуальный хостинг и теперь вы можете вытворять все, что вашей душе угодно. Собственно, к чему и шли.</p>
<p>Еще можно поставить phpMyAdmin для удобства работы с БД, поднять свой DNS и все остальное. Но это по желанию. </p>
<p>Если вы все это делаете впервые, то самым правильным решением будет попытаться написать bash скрипт, который автоматизирует процесс создания хостов, перезапуска серверов и прочего. И дело полезное сделаете и знания полученные закрепите. Если я таки найду время набросать пару скриптов, выложу их здесь.</p>
<p>Еще настоятельно рекомендую почитать документацию по Nginx и Apache, особенную ту ее часть, где описывается правильное конфигурирование виртуальных хостов.</p>
<p>Собственно, на этом все.</p>
<p>P.S: Совершенно не факт, что я все делал правильно, поэтому, если вам есть что сказать или вы можете указать на мои конкретные ошибки, пишите в комментариях. Спасибо.</p>
<h2>Тестируем на нагрузку</h2>
<p>Как только весь этот зоопарк заработал, я решил проверить сервер на нагрузку и сравнить результаты с тестом того же сайта, но на виртуальном хостинге. Тестировалось через бесплатный аккаунт на <a href="http://loadimpact.com/" target="_blank" rel="external nofollow">loadimpact.com</a>.</p>
<h3>Тест на VPS</h3>
<p><img style="border: #666 1px solid" src="/wp-content/uploads/2011/08/vps_test.png" alt="" title="vps_test" width="547" height="537" class="aligncenter size-full wp-image-658" /></p>
<h3>Тест на Sweb.ru</h3>
<p><img style="border: #666 1px solid"  src="http://inroot.ru/wp-content/uploads/2011/08/sweb_test.png" alt="" title="sweb_test" width="541" height="540" class="aligncenter size-full wp-image-661" /></p>
<p>Я думаю, что разница очевидна и можно обойтись без лишних слов. VPS и глазом не моргнул. Ну а реакция виртуального хостинга вполне ожидаема и, нужно отдать должно, положительно удивила меня. Я думал, что все будет значительно хуже.</p>
<p>Также предлагаю ознакомиться с графиками из панели управления VPS. По ним вы можете судить о том, как сервер реагировал на возрастающую нагрузку.</p>
<div class="aligncenter">
<img style="border: #666 1px solid" src="http://inroot.ru/wp-content/uploads/2011/08/stats_cpu.png" alt="" title="stats_cpu" width="662" height="183" class="aligncenter size-full wp-image-662" /></p>
<p><img style="border: #666 1px solid" src="http://inroot.ru/wp-content/uploads/2011/08/stats_ram.png" alt="" title="stats_ram" width="674" height="183" class="aligncenter size-full wp-image-665" /></p>
<p><img style="border: #666 1px solid" src="http://inroot.ru/wp-content/uploads/2011/08/stats_hdd.png" alt="" title="stats_hdd" width="680" height="189" class="aligncenter size-full wp-image-666" />
</div>
<blockquote><p><strong>UPD:</strong><br />
А вот и <a href="/2011-08/bash-script-virtual-hosts-apache-nginx.html">bash скрипт создания виртуальных хостов</a>, как и обещал. Надеюсь, он поможет вам написать собственный, в разы более функциональный и удобный.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-08/linux-server-apache-nginx-mysql-php-proftpd.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Двойной CSS background</title>
		<link>http://inroot.ru/2011-07/dual-css-background-hack.html</link>
		<comments>http://inroot.ru/2011-07/dual-css-background-hack.html#comments</comments>
		<pubDate>Sun, 03 Jul 2011 16:25:52 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[CSS/xHTML]]></category>
		<category><![CDATA[CSS background]]></category>
		<category><![CDATA[CSS tricks]]></category>
		<category><![CDATA[CSS хаки]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=579</guid>
		<description><![CDATA[Работая над одним из проектов, я столкнулся с необходимостью задать одновременно два фоновых изображения для страницы. Этого требовал макет дизайна, в котором левая и правая половины страницы имели разные бэкграунды. Спецификация CC3 поддерживает такую возможность, но, увы, даже в наше время активного развития WEB, далеко не все браузеры полноценно поддерживают 3-ю версию CSS. А хотелось [...]]]></description>
			<content:encoded><![CDATA[<p>Работая над одним из проектов, я столкнулся с необходимостью задать одновременно два фоновых изображения для страницы. Этого требовал макет дизайна, в котором левая и правая половины страницы имели разные бэкграунды.</p>
<p>Спецификация CC3 поддерживает такую возможность, но, увы, даже в наше время активного развития WEB, далеко не все браузеры полноценно поддерживают 3-ю версию CSS. А хотелось бы, конечно, найти кросс-браузерное решение, доступное даже таким мамонтам, как, например, Internet Explorer 7.</p>
<p>Вариант с вырезанием одного большого фонового изображения никак не подходит. Во-первых, это совсем плохая идея, особенно если можно обойтись без таких радикальных мер, во-вторых, требовалось, чтобы фон заполнял страницу по ширине при любом экранном разрешении.</p>
<p><span id="more-579"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Конечно, хотелось бы найти решение, не требующее дополнительной HTML разметки, но в итоге оказалось, что без этого не обойтись. Все же, найденное решение работает и работает хорошо.</p>
<p>Начнем с HTML разметки, которая потребует использования дополнительного контейнера:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;second_bg&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;content&quot;</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">img</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;./images/header_image.png&quot;</span> <span style="color: #000066;">alt</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></pre></td></tr></table></div>

<p>Дополнительный контейнер имеет ID second_bg. Ниже может идти привычная для вас разметка страницы. Одним из плюсов данного способа является простота его внедрения в уже существующую верстку. Так как дополнительный контейнер позиционируется абсолютно, почти наверняка, его появление в коде не создаст никаких дополнительных трудностей.</p>
<p><strong>CSS для body и #second_bg</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="css" style="font-family:monospace;">body <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">font</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">normal</span> <span style="color: #933;">75%</span> Tahoma<span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#e5e5e5</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'./images/bg_body_0.gif'</span><span style="color: #00AA00;">&#41;</span> <span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">top</span> <span style="color: #993333;">repeat-x</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
<span style="color: #cc00cc;">#second_bg</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">50%</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">96px</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">position</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">absolute</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">left</span><span style="color: #00AA00;">:</span> <span style="color: #933;">50%</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">transparent</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'bg_body_1.gif'</span><span style="color: #00AA00;">&#41;</span> <span style="color: #993333;">repeat-x</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></td></tr></table></div>

<p>Если слой с фоном будет перекрывать какой-то элемент, просто задайте этому элементу относительно позиционирование, также можете поиграться с z-index.</p>
<p>Как видно из кода селектора, вся суть в ширине слоя и его позиции в 50% от левого края. Таким образом, достигается нужный нам эффект.</p>
<p>В завершении, предлагаю посмотреть <a href="/files/dual_css_background/" target="blank">рабочий пример</a> и изучить полный код страницы, если это потребуется.</p>
<p><a href="/files/dual_css_background/" target="blank"><img src="http://inroot.ru/wp-content/uploads/2011/07/demo.png" alt="" title="Двойной CSS background - онлайн демо" width="64" height="64" class="alignleft" /></a></p>
<p>За основу была принята вот <a href="http://cherny.com/webdev/11/dual-background-images" target="_blank" rel="nofollow external">эта публикация</a>. Сначала думал сделать перевод, но как-то не сложилось. Тем не менее, копирайт и все такое &#8211; сослаться обязан!</p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-07/dual-css-background-hack.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CodeIgniter 2.0 + HMVC + шаблонизатор Dwoo</title>
		<link>http://inroot.ru/2011-05/codeigniter-2-0-hmvc-and-dwoo.html</link>
		<comments>http://inroot.ru/2011-05/codeigniter-2-0-hmvc-and-dwoo.html#comments</comments>
		<pubDate>Sat, 28 May 2011 08:14:15 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[Dwoo]]></category>
		<category><![CDATA[HMVC]]></category>
		<category><![CDATA[Модульность CodeIgniter]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=561</guid>
		<description><![CDATA[Хочу рассказать о том, как свести вместе CodeIgniter версии 2.* и две достаточно популярных библиотеки для этого фреймворка: шаблонизатор Dwoo и библиотеку Modular Extensions &#8211; HMVC. Версии ПО: CodeIgniter 2.0.2 Dwoo 1.1.1 CodeIgniter HMVC 5.4 Для начала ставим сам CodeIgniter. Там ничего сложного и нужный эффект достигается путем распаковки файлов. Далее, на чистый CI, ставим [...]]]></description>
			<content:encoded><![CDATA[<p>Хочу рассказать о том, как свести вместе <strong>CodeIgniter</strong> версии 2.* и две достаточно популярных библиотеки для этого фреймворка: <strong>шаблонизатор Dwoo</strong> и библиотеку <strong>Modular Extensions &#8211; HMVC</strong>.</p>
<p>Версии ПО:</p>
<ul>
<li><a rel="nofollow" target="_blank" href="http://codeigniter.com/">CodeIgniter 2.0.2</a></li>
<li><a rel="nofollow" target="_blank" href="http://dwoo.org/">Dwoo 1.1.1</a></li>
<li><a rel="nofollow" target="_blank" href="https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/wiki/Home">CodeIgniter HMVC 5.4</a></li>
</ul>
<p>Для начала ставим сам CodeIgniter. Там ничего сложного и нужный эффект достигается путем распаковки файлов.</p>
<p>Далее, на чистый CI, ставим HMVC. Процесс установки HMVC описан специально для CodeIgniter версии 2.*. Добавить от себя нечего, поэтому привожу перевод официального мануала.<br />
<span id="more-561"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<ol>
<li>Начните с чистым CI</li>
<li>Установите верное значение для $config["base_url"] в файле /application/config/config.php</li>
<li>Обратитесь по URL /index.php/welcome. Вы должны увидеть «Welcome to CodeIgniter»</li>
<li>Скопируйте директорию third_party в директорию /application/ (с заменой файлов)</li>
<li>Скопируйте директорию core в директорию /application/ (с заменой файлов)</li>
<li>Обратитесь по URL /index.php/welcome. Вы должны увидеть «Welcome to CodeIgniter»</li>
<li>Создайте директорию модуля welcome &#8211; /application/modules/welcome/controllers</li>
<li>Переместите контроллер application/controllers/welcome.php в application/modules/welcome/controllers/welcome.php</li>
<li>Обратитесь по URL /index.php/welcome. Вы должны увидеть «Welcome to CodeIgniter»</li>
<li>Создайте директорию /application/modules/welcome/views</li>
<li>Скопируйте файл представления /application/views/welcome_message.php в /application/modules/welcome/views/welcome_message.php</li>
<li>Обратитесь по URL /index.php/welcome. Вы должны увидеть «Welcome to CodeIgniter»</li>
</ol>
<p>Установка завершена.</p>
<p>Несмотря на то, что необходимости в этом нет, я предлагаю сразу создать базовый контроллер, который будем расширять контроллерами модулей. Раз уж мы накатили HMVC, то почему бы не сделать этого.</p>
<p>Создадим файл /application/core/MY_Controller.php c вот таким вот содержимым:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'BASEPATH'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> OR <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'No direct script access allowed'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* load the MX_Loader class */</span>
<span style="color: #b1b100;">require</span> APPPATH<span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;third_party/MX/Controller.php&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> MY_Controller <span style="color: #000000; font-weight: bold;">extends</span> MX_Controller
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        parent<span style="color: #339933;">::</span>__construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Теперь в этом классе можно организовать проверку авторизации пользователя, разграничение прав доступа и прочее.  Но в данном конкретном случае он потребуется только для централизованного подключения библиотек, которые должны быть доступны всему приложению, а именно шаблонизатора.</p>
<h2>Устанавливаем шаблонизатор Dwoo</h2>
<ol>
<li>Распаковываем Dwoo/Adapters/CodeIgniter в /application/</li>
<li>Полностью распаковываем библиотеку в /application/libraries/</li>
<li>В файле /application/config/dwootemplate.php  меняем настройки на ваши</li>
</ol>
<p>У меня файл настроек имеет следующее содержание:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'BASEPATH'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'No direct script access allowed'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// The name of the directory where templates are located.</span>
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'template_dir'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../views/'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// The directory where compiled templates are located</span>
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'compileDir'</span><span style="color: #009900;">&#93;</span>   <span style="color: #339933;">=</span> <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../views/__compile/'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//This tells Dwoo whether or not to cache the output of the templates to the $cache_dir.</span>
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'caching'</span><span style="color: #009900;">&#93;</span>      <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'cacheDir'</span><span style="color: #009900;">&#93;</span>     <span style="color: #339933;">=</span> <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../views/__cache/'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'cacheTime'</span><span style="color: #009900;">&#93;</span>    <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Несмотря на то, что мы используем <strong>HMVC</strong>, которая позволяет для каждого модуля иметь свою директорию views, я предпочитаю все шаблоны хранить в одном месте, поэтому пользуюсь /application/views/, как и задумано изначально в <strong>CodeIgniter</strong>. С учетом этого, я здесь же храню компилированные шаблоны и их кэш. Если у вас иная политика, меняйте настройки в dwootemplate.php на свой вкус.</p>
<p>Теперь небольшие грабли. Увы, адаптер не рассчитан на последние версии CodeIgniter, поэтому библиотека <strong>Dwootemplate</strong> требует напильника. Во-первых, из коробки она просто не работает, так как в методе <tt>Dwootemplate::display()</tt> осуществляется обращение к свойству <tt>Output::$final_output</tt>, которое объявлено с модификатором protected. Для решения проблемы, в файле /application/libraries/Dwootemplate.php ищем строку</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$CI</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">final_output</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$template</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>И заменяем ее на</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$CI</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set_output</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$template</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Также я заменил все строки</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$CI</span> <span style="color: #339933;">=</span> get_instance<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>на</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$CI</span> <span style="color: #339933;">=</span> CI_Controller<span style="color: #339933;">::</span><span style="color: #004000;">get_instance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>После этого все работает но на самом деле, имеет смысл написать свою обертку для Dwoo. Класс Dwootemplate обладает достаточно скромными возможностями и сгодится лишь для простеньких задач. Правильнее взять его за основу и написать свой, более гибкий и функциональный. Но это уже отдельный разговор.</p>
<p>Осталось все проверить на работоспособность.<br />
Открываем файл /modules/welcome/controllers/welcome.php и заменяем метод <tt>Welcome::index()</tt> на следующий:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">load</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">library</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Dwootemplate'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dwootemplate</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assign</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'itshowlate'</span><span style="color: #339933;">,</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'H:i:s'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dwootemplate</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">display</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'dwoowelcome.tpl'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>В принципе, мы собрали и подготовили базовый набор для написания практически любого приложения, например, небольшой CMS.</p>
<p>Публикую дистрибутив Dwoo и HMVC. Делаю это для того, чтобы в случае выхода новых версий этих библиотек, статья оставалась актуальной. Тем не менее, само собой, следует использовать последние версии ПО. </p>
<p>Также выкладываю уже патченный /application/libraries/Dwootemplate.php</p>
<blockquote><p>
<strong>Файлы:</strong><br />
<a href='http://inroot.ru/2011-05/codeigniter-2-0-hmvc-and-dwoo.html/dwoo-1-1-1-tar' rel='attachment wp-att-566'>dwoo-1.1.1.tar</a><br />
<a href='http://inroot.ru/2011-05/codeigniter-2-0-hmvc-and-dwoo.html/wiredesignz-codeigniter-modular-extensions-hmvc-89f47c3248f7' rel='attachment wp-att-567'>modular-extensions-hmvc</a><br />
<a href='http://inroot.ru/2011-05/codeigniter-2-0-hmvc-and-dwoo.html/dwootemplate' rel='attachment wp-att-568'>Dwootemplate</a></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-05/codeigniter-2-0-hmvc-and-dwoo.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Где на Руси жить хорошо. Пару слов о фрилансе</title>
		<link>http://inroot.ru/2011-05/about-freelance-part-1.html</link>
		<comments>http://inroot.ru/2011-05/about-freelance-part-1.html#comments</comments>
		<pubDate>Tue, 10 May 2011 23:50:26 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Вольнодумье]]></category>
		<category><![CDATA[Freelance]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=532</guid>
		<description><![CDATA[Любой фрилансер, рано или поздно, пишет в свой блог о фрилансе. Это как дань моде или традиция. Я на вольных хлебах уже почти два года и, думаю, что время пришло. Особенно мне есть что сказать, сейчас, когда к моменту сдачи приближаются несколько совершенно разных проектов, каждый из которых принес свой бесценный опыт. Это первая заметка. [...]]]></description>
			<content:encoded><![CDATA[<p>Любой фрилансер, рано или поздно, пишет в свой блог о фрилансе. Это как дань моде или традиция. Я на вольных хлебах уже почти два года и, думаю, что время пришло. Особенно мне есть что сказать, сейчас, когда к моменту сдачи приближаются несколько совершенно разных проектов, каждый из которых принес свой бесценный опыт.</p>
<p>Это первая заметка. Остальные будут позже и окажутся более практичными. Сейчас я просто хочу полить воды на горячие камни. Потрепаться, так скажем.</p>
<p>Прежде всего, следует учитывать, что фриланс – штука индивидуальная. Каждый из нас имеет свою сферу деятельности, количество профессионального опыта, а также багаж в виде трудолюбия и самоконтроля.</p>
<p>Начну я с начала, а именно с того, почему некоторые офисные работники уходят свободный поиск.  Пойдем по списку.<br />
<span id="more-532"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<ol>
<li>Я не хочу работать на «дядю».
<li>На фрилансе я сам буду решать, за какую работу браться, а какую слать к черту.
<li>Я смогу зарабатывать больше. В офисе меня нихрена не ценят.
<li>В офисе некомфортно. Шумно, много людей. Все отвлекают.
<li>Буду экономить время на дороге, следовательно, делать свою работу быстрее.
<li>Я смогу работать там и тогда, когда мне это удобно.
</ol>
<p>Нумерация здесь не отражает хронологию или приоритет, хотя, бесспорно, первый пункт звучит наиболее часто.</p>
<p>Вполне возможно, у вас другой список, но, я уверен, большую часть всего этого вы неоднократно говорили или думали. Я также имею возможность общаться с другими фрилансерами и прекрасно помню свои мыски, когда я покидал последний офис. Список достаточно объективен и весьма актуален. Для чего он? Если вкратце, то все это – бред!</p>
<p>1. Можно ли считать благом отсутствие официального трудоустройства? Сомнительно. Во-первых, вы лишаете себя самого минимального социального пакета. Например, никакой вам теперь медицинской страховки. Также забудьте про сколько-нибудь серьезные кредиты в банке. Вам их не дадут. Даже при съеме жилья придется врать. Никто не хочет сдавать квартиру безработному, а фрилансеры именно таковыми являются. Кстати, не каждое посольство даст вам визу. США, например, очень не любит безработных, имейте ввиду. Перечислять можно долго, но самое главное, действительно ли вы теперь не работаете на «дядю»? А кем является каждый ваш заказчик? Это такой же работодатель только с тараканами, о которых вы ничего не знаете. Если своего руководителя вы знали на отлично и всегда понимали, когда его лучше не дергать или наоборот, можно подкатить с просьбой дать отгул. То теперь хрен. Каждый клиент – темная лошадка, у которой может меняться настроение от силы порыва ветра.</p>
<p>2. Да, так и есть, но до поры до времени. Крутить носом получается, когда денег куры не клюют. А если предыдущий месяц не выдался урожаем, то браться вы будите за все, что сколько-нибудь кормит. Конечно, все зависит от того, насколько вы успешны, но поверьте, черная полоса не минет и вас. Четко осознавайте, что далеко не всегда получается работать в удовольствие. Особенно, учитывая тот факт, что на фриланс, как правило, клиент приходит в поиске тех, кто сможет исправить возникшие проблемы. То есть основная часть работы – это правки и доработки уже чего-то, что сделано не вами. Соответственно, мне, как программисту, часто приходится сталкиваться с тоннами говно-кода. Вряд ли можно назвать это работой в радость.</p>
<p>3. Вот это полная херня. Кто это придумал и на каком основании? И почему люди в это так наивно верят? Да, теоретически, вы сможете зарабатывать больше, но готовьтесь к тому, что ваш рабочий день будет составлять 25 часов в сутки. Расклад простой. В офисе вы делали только ту работу, которая вам предписывалась по должности. Сейчас в ваши обязанности войдет необходимость переписки с клиентами, поиска заказов, предварительного ознакомления с ТЗ и прочее.  На все это уходит огромное количество времени, зачастую значительно большее, нежели время на выполнение задания непосредственно. Ко всему прочему, например, если вы программист, в офисе вы работали с корпоративной CMS, которую знали вдоль и поперек. На фрилансе каждый клиент приходит со своим «самоваром», в котором вам сначала придется разобраться, а уже потом его дописывать.</p>
<p>4. Да, верно.  Офисный планктон много курит, пьет кофе и никогда не откажется потрепаться о незыблемом. Соблазнов заниматься херней предостаточно. Но уверены ли вы в том, что дома их будет меньше? Семья, друзья и любимый хомяк не скоро поймут, что если вы дома, это не значит, что вы свободны и готовы составить им компанию за чашкой чая или же вас просто можно отправить в магазин за пакетом картошки и молоком. Прошло не меньше полугода, прежде чем мои родные таки осознали, что я работаю и меня не нужно дергать по поводу и без, ну а нормально я смог работать только тогда, когда переехал. Про такие внешние раздражители как зомбоящик и компьютерные игры я вообще молчу.</p>
<p>5. Читайте пункт 4. В нем я уже ответил и на эту глупость. Можно еще добавить, что время, которое вы сэкономили, уйдет явно не на работу. У вас появится повод подольше поспать, побольше пожрать и покурить на балконе с чашкой кофе. Также заметно больше времени будет на чтение блогов, посещение социальных сетей и прочую фигню, но никак не на работу.</p>
<p>6. Ага, конечно. Там – это где? Я пробовал работать на даче, например. Назвать атмосферу рабочей язык не поворачивается. Ну а настроение тем более.<br />
А работать вам придется тогда, когда это удобно вашим заказчикам. Никто не будет в восторге от того, что вы весь день мнете морду об подушку, а к работе приступаете ночью. Любой клиент желает, чтобы вы были на связи именно в рабочее время. Более того, для некоторых проектов это обязательное требование. В итоге, как не крути, а все равно придется быть онлайн днем, хотя бы с 12 и до 20:00. Также не забывайте о тех клиентах, что живут в других часовых поясах. С ними вам тоже придется общаться именно тогда, когда это удобно им. В итоге, ваш рабочий день превращается в рабочие сутки.</p>
<p>На самом деле, продолжать можно бесконечно. Мифов существует более чем достаточно. Да, в каждом из них есть капля правды, но это совсем не то, на что вы могли надеяться.</p>
<p>Тем не менее, без положительных моментов никуда. Иначе не было бы такого понятия, как фриланс. Ведь почему-то люди опускаются в это болото и здесь остаются, многие навсегда. Давайте и об этом поговорим.</p>
<p>Конечно, работать «на себя» приятно. Пусть это условность и не до конца правда, но отчасти это действительно так. Если вам позволяют обстоятельства, вы можете браться только за ту работу, которая вам нравится. К сожалению, это не всегда возможно, но гораздо реальнее, нежели в офисе. Там у вас никогда не бывает выбора, здесь он есть в тех или иных случаях.</p>
<p>В целом, решение любого вопроса зависит только от вас. Иногда такая свобода и количество ответственности откровенно напрягают и грузят, иногда наоборот, это придает сил. Вы будете успешны настолько, насколько хватит ваших талантов. Любой завершенный проект – только ваша заслуга. То, сколько вы заработали – плоды вашего труда. Но и провалы чувствуются гораздо острее. Всегда трудно осознавать, что в вашей лаже никто кроме вас не виноват. Свалить вину на кого-то уже не получится.</p>
<p>Что касается свободного времени, то здесь все зависит от вашей самоорганизации. Если сильно напрячься, можно успевать многое. Я этому так до конца и не научился. Иногда сложно заставить себя приступить к работе, иногда наоборот – трудно осознать факт того, что загруз уже максимальный и не нужно набирать работы еще больше. В итоге, сидишь, обложившись горящими проектами и думаешь только о том, как бы ласты не склеить. Но я всегда могу устроить себе выходной, пусть он будет и за мой счет. Могу дать себе бессрочный отпуск, несмотря на то, что это грозит последующей неизбежной диетой. Но по факту, в случае необходимости, я таки могу это сделать. В офисе такого не простят.</p>
<p>Что касается денег, то да – можно зарабатывать больше, но только ценой больших трудозатрат, значительно превышающих те, что вы позволяли себе в офисе. Тем не менее, если вам нечем заняться, можно забить время работой и превратить его в деньги. На рабочем месте такое неосуществимо, так как выше оклада не прыгнешь, хоть из кожи вылези. Премии и прочие подачки я в учет не беру, это не те суммы, о которых можно говорить и далеко не везде ими балуют.</p>
<p>Ну и самое главное, что я для себя нашел на фрилансе – бесценный опыт. Во-первых, появилась отличная возможность развивать свои коммуникативные навыки и навыки менеджера по продажам. Вряд ли еще где-либо вы столкнетесь с необходимостью настолько умело продавать свои услуги, как на рынке фриланса. Всегда есть возможность вытащить ценник на тот уровень, который удобен вам, добиться лучших условий сотрудничества, отказаться от тех решений, которые вам неудобны и заменить их другими, снижающими ваши трудозатраты. Во-вторых, любой проект – это в той или иной степени нестандартное решение. Даже самые тривиальные задачи содержат оговорки и свои особенности, что заставляет вас регулярно расширять свой кругозор актуальных технологий. Например, с XSL я познакомился только на фрилансе. Здесь же я получил опыт работы с новым для себя БД, с массой неплохих CMS, взял на вооружение дюжину новых алгоритмов и прочее. Для офисного работника никогда не будет такого раздолья. Любая компания движется по накатанной дорожке: корпоративная CMS, отстроенный цикл разработки и прочее. В итоге, любой проект превращается в выполнение одних и тех же телодвижений. Само собой, количество опыта, который вы получите, напрямую зависит от вашего собственного желания. Можно продолжать тупить, как и прежде, но предпосылок для развития все равно больше.</p>
<p>В общем, фриланс – это сложно, но интересно. Есть к чему стремиться, куда двигаться. Перспективы, кажется, менее очевидны, но их значительно больше. Запасайтесь терпением. Успехов! </p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-05/about-freelance-part-1.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHPShop или встреча с дьяволом</title>
		<link>http://inroot.ru/2011-03/phpshop-or-meeting-with-sotona.html</link>
		<comments>http://inroot.ru/2011-03/phpshop-or-meeting-with-sotona.html#comments</comments>
		<pubDate>Tue, 29 Mar 2011 01:57:58 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Вольнодумье]]></category>
		<category><![CDATA[Разное]]></category>
		<category><![CDATA[PHPShop]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=492</guid>
		<description><![CDATA[Так как я являюсь фрилансером уже почти два года, само собой, что за это время я успел повидать немало различных программных решений: от самопальных скриптов, писаных в пьяном бреду, до громоздких и навороченных социальных движков, реализованных с использованием паттернов и и прочих прелестей программисткой мысли. Конечно, как любой разработчик, я почти никогда не бываю доволен [...]]]></description>
			<content:encoded><![CDATA[<p><img class="post_cover" src="http://inroot.ru/wp-content/uploads/2011/03/phpshop_logo.png" alt="Отзыв о движке интернет магазина PHPShop" title="Отзыв о движке интернет магазина" width="150" height="150" class="alignleft size-full wp-image-496" /></p>
<p>Так как я являюсь фрилансером уже почти два года, само собой, что за это время я успел повидать немало различных программных решений: от самопальных скриптов, писаных в пьяном бреду, до громоздких и навороченных социальных движков, реализованных с использованием паттернов и и прочих прелестей программисткой мысли.</p>
<p>Конечно, как любой разработчик, я почти никогда не бываю доволен тем, с чем приходится работать. Всегда есть свои взгляды на самые тривиальные, казалось бы, вопросы. Всегда присутствует «я сделал бы здесь по-другому», но всегда в меру. Бывало я хотел убить авторов того или иного приложения, ну или просто оторвать им руки. Иногда я хотел эти руки пожать и дружески обнять тех, кто писал такой понятный и красивый код. Как бы там ни было, никогда не доходило до того, чтобы я писал гневные посты в блог или куда-либо еще. Но все бывает в первый раз и это случилось сегодня…</p>
<p>Добро пожаловать на церемонию торжественной казний PHPShop!</p>
<p><span id="more-492"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Не знаю как вы, но до недавнего времени я никогда даже не слышал об этом движке интернет магазина. Это, по меньшей мере, странно, ведь ребята продают <s>пирожки</s> свой продукт на рынке с 2004 года. Согласитесь, хоть краем уха, но слышать должен был.</p>
<p>Для начала замечу, что скрипт платный и стоит, если сравнивать с прочими подобными, весьма не дешево, а целых 11790 рублей (март 2011). Я бы попросил вас запомнить этот факт и обращать на него внимания по ходу чтения заметки. </p>
<p>Мое недовольство начинает рождаться в глубинах сознания уже с первых минут знакомства. Прежде всего, жутко не понравилось то, что некоторые файлы закрыты зендом. Достаточно давно миновали те времена, когда можно было париться за секретность каких-нибудь гениальных программных решений. Все уже давно решено и лежит в открытом доступе. К чему создавать лишние трудности тем, кто захочет поработать напильником. А поработать есть над чем и напильник потребуется немалый…</p>
<p>Второй приступ восторга вызвала админка, которую некто умный, проникшийся столпами юзабилити, сделать целиком и полностью на pop-up окнах. Мало того, что половину pop-up’ов блокирует глушилка рекламы, так вы еще может забыть про работу с админкой из нескольких вкладок. Вместо вкладок, чертова хрень плодит отдельные окна самого браузера. Первое время я никак не мог к этому привыкнуть и постоянно терял открытые поп-апы.</p>
<p>Еще больше позитива добавляли JavaScript ошибки, загадившие всю консоль Firebug’а. Я сразу понял, что с PHPShop мы поладим, и работа будет веселой и непринужденной (это сарказм, если что, но скучно действительно не было).</p>
<p>Поставленные задачи были просты:</p>
<ul>
<li><strong>Сверстать и нацепить шаблон</strong></li>
<li><strong>Настроить движок</strong></li>
<li><strong>Набить базу несколькими примерами контента</strong></li>
</ul>
<p>Я решил начать с предварительной настройки. И сразу сюрприз! Местами админка банально не работает.  Указанные настройки просто не сохраняются, хоть ты тресни. Например, в настройках категорий товаров можно выбрать количество товаров, выводимых в одну строку, при просмотре содержимого категории. Мало того, что есть всего четыре варианта выбора (от 1 до 4 товаров в ряд), так из них работает только три :) Вариант с четырьмя товарами просто не сохраняется… А как думаете, сколько нужно было мне? Бинго! Мне нужно было 4 товара в ряд.</p>
<p>Пошел  я смотреть в код, отчего же оно так все плохо. И тут плохо стало мне… Такого ужаса я не видел давно. То, что код не структурирован отступами – дело обыденное, а вот имена переменных из одной или двух букв повергли меня под стол. Увы, мой личный телепат ушел в декретный отпуск, поэтому о значении переменных с именами $ij, $j, $k и так далее, мне приходилось догадываться самостоятельно. А таких переменных там около 30% от общего числа. С таким я встретился впервые.</p>
<p>Далее я долго смеялся над транслитерированными именами лексем. Например, вы можете найти следующие шедевры:</p>
<blockquote><p>
Vivod_cat_table()<br />
$SysValue['my']['setka_num']<br />
$LoadItems['Podcatalog']
</p></blockquote>
<p>То есть чупакабра, которая писала код, знала некоторое количество английских слов, но совсем небольшое. Нет, ну если в школе тебе сильно били и ты пропускал уроки английского,  то почему бы не поискать слово «display в словаре? А правильно, нафиг, пусть «Vivod» убьет умы людей!</p>
<p>К слову, проблема имен коснулась не только переменных и функций, но и директорий, файлов и всего остального. Авторский стиль выдержан на твердую пять!</p>
<p>Дальше мне предстояло заняться одеванием шаблона. То, что это будет не самая простая задача, я уже понял, так как в скриптах забито огромное количество HTML кода, а значит, сами шаблоны большой гибкостью не отличаются. Знал бы я тогда, насколько сильно я ошибаюсь.</p>
<p>Если вы не знаете PHP, то сделать адекватную верстку для PHPShop вы не сможете. Как я уже сказал, очень много кода содержится в самих скриптах. Причем не какой-нибудь там строки пагинации или кнопки десятой важности, а вывода списка товаров, например. Более того, код, зашитый в скрипты, содержит незакрытые HTML тэги. А так как авторы PHPShop таблицами не брезговали, вылавливать глюки верстки вы замучаетесь.</p>
<p>Что касается встроенного шаблонизатора, то его в общем-то и нет. Ту хрень, что предлагают авторы движка, никак нельзя назвать шаблонизатором. Никаких вам  привычных {foreach} или {loop}, никаких условных операторов {if}. Шаблонизатор этого просто не умеет. Все, что он может – подставлять данные на место переменных вида <tt>@imya_peremennnoi@</tt>. Как с таким инструментарием сделать вменяемые и функциональный шаблон? Увы, ответа я не нашел.</p>
<p>Кстати об ответах. Решать проблемы вам придется самостоятельно потому, что никакой вменяемой справки нет. Та документация, что предлагают на сайте – набор букв. Найти в ней  нечто, несущее пользу нереально, вполне возможно потому, что там этого нет. Форум тоже отсутствует. Его роль выполняет гостевая книга – еще одно гениальное решение разработчиков. Они бы еще чат для этих целей использовали.</p>
<p>Что касается отстраненных впечатлений, то они тоже далеко не лучшие. Движок неудобен во всех отношениях. Админка кривая, как кочерга. Для человека неискушенного она не помощник, а препятствие. Учитывая недоработки, которых в ней с избытком, я боюсь даже представить, как малоопытный владелец такого интернет магазина сможет с ним управляться. Об интуитивности интерфейса я даже говорить не стану. Функциональные возможности движка также на нуле. Кроме организации магазина и новостной ленты, по сути, он толком больше ничего не умеет. Рубрикатор в магазине может быть всего двух уровней, то есть, сложной системы каталога добиться не получится.</p>
<p>Резюмируя и подводя итоги, предлагаю вам вспомнить стоимость данного скрипта и сопоставить ее с теми фактами, которые я здесь привел. Честно говоря, я просто в ужасе от того, какие программные решения и за какие деньги продаются. Еще хуже то, что эти решения покупают и используют.</p>
<p>Анафеме предан без права на права! Засим все…</p>
<blockquote><p><strong>UPD 16.08.11:</strong><br />
Сегодня в бэках яндекса наткнулся на &#8220;<a target="_blank" rel="external nofollow" href="http://forum.phpshopcms.ru/index.php?showtopic=1141">ответ Чемберлену</a>&#8221; от автора PHPshop. Думаю, комментариев не нужно. Товарищ Dennion ушел дискутировать среди своих :)</p>
<p>P.S: Из всей истории делаю один вывод &#8211; про PHPShop или хорошо, или никак, равным счетом, как об усопших. Критика, конструктивная, я считаю, ибо везде по пунктам и с конкретными претензиями, вызывает неадекватную реакцию.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-03/phpshop-or-meeting-with-sotona.html/feed</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>CodeIgniter и Matchbox: часть вторая</title>
		<link>http://inroot.ru/2011-03/codeigniter-and-matchbox-troubles-with-app-routing-part-2.html</link>
		<comments>http://inroot.ru/2011-03/codeigniter-and-matchbox-troubles-with-app-routing-part-2.html#comments</comments>
		<pubDate>Fri, 18 Mar 2011 00:44:57 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[Matchbox]]></category>
		<category><![CDATA[Модульность CodeIgniter]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=448</guid>
		<description><![CDATA[Пол года назад я уже писал о CodeIgniter и Matchbox, о проблемах, которые возникают при использовании этой библиотеки и о своих попытках с ними бороться. Я думаю, если вы здесь, то уже знаете что такое Matchbox и для чего он нужен. Если я ошибаюсь, то хочу предложить вам ознакомиться с первой заметкой на эту тему. [...]]]></description>
			<content:encoded><![CDATA[<p><img class="post_cover" src="http://inroot.ru/wp-content/uploads/2011/03/codeigniter-lg-150x150.gif" alt="CodeIgniter и Matchbox: часть вторая" title="codeigniter-lg" width="150" height="150" class="aligncenter size-thumbnail wp-image-454" /></p>
<p>Пол года назад я <a href="/2010-10/codeigniter-and-matchbox-troubles-with-application-routing.html" target="_blank">уже писал</a> о <strong>CodeIgniter и Matchbox</strong>, о проблемах, которые возникают при использовании этой библиотеки и о своих попытках с ними бороться. Я думаю, если вы здесь, то уже знаете что такое  Matchbox и для чего он нужен. Если я ошибаюсь, то хочу предложить вам ознакомиться с <a href="/2010-10/codeigniter-and-matchbox-troubles-with-application-routing.html" target="_blank">первой заметкой</a> на эту тему. В ней вы найдете краткое  (не более краткое, чем официальная документация) описание Matchbox и другое словоблудство на эту тему.</p>
<p>Как я уже сказал, в первом своем упоминании о Matchbox я не только озвучил существующую проблему (на самом деле, она не одна), но и пытался найти решение оной. Решение это не что иное, как полуживой костыль, работающий с божьей помощью. Как водится, довести его до ума времени я так и не нашел, но нашел тех, кто это сделал за меня!<br />
<span id="more-448"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p><br />
Один знакомый из интернетов, также страдающий от кривизны Matchbox, собрал с форумов и прочих конференций всевозможные патчи и фиксы для этой библиотеки. Объединил все это в один архив и вежливо со мной им поделился. Признаться, не знаю, сам ли он прошел этот путь собирателя или тоже где-то выклянчил готовое решение, но факт остается фактом &#8211; хреновина заработала!</p>
<p>Собственно, кому не интересно слушать дальше, могут сразу забрать аттач (ссылка в конце), для остальных обещаю еще пару-тройку абзацев текста.</p>
<p>Желая исключить возможные разночтения, оговорюсь, что работаю я с ПО следующих версий:</p>
<ul>
<li><strong>CodeIgniter 1.7.2</strong></li>
<li><strong>Matchbox RC2</strong></li>
</ul>
<p>Уже на момент написания этих букв существует CodeIgniter 2.0. Его я на вкус не пробовал, поэтому будьте готовы к нестыковкам.  Matchbox не обновляется с сентября 2009 года. То есть Matchbox RC2  &#8211; последняя версия на текущий момент и, что-то мне подсказывает, последняя в принципе.</p>
<p>Увы, выложенный мною патч тоже не панацея. Например, в нем не реализован метод <tt>CI_Loader:: module_model()</tt>. Совсем не критично и за все время активного пользования фреймворком и библиотекой, только один раз возникал соблазн и желание вызвать «чужую» модель. Может быть не работает что-то еще, о чем я не знаю. Но используя связку <strong>CodeIgniter + Matchbox + Matchbox FIX</strong>, мне удалось написать небольшую  рабочую CMS. Из этого делаю вывод, что объект внимания съедобен и имеет право на жизнь в живых проектах.</p>
<p><strong>Собственно, то самое:</strong></p>
<blockquote><p><a href='http://inroot.ru/2011-03/codeigniter-and-matchbox-troubles-with-app-routing-part-2.html/matchbox_fix' rel='attachment wp-att-449'>matchbox_fix</a></p></blockquote>
<p>Будут вопросы, пишите в комменты. Успехов!</p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-03/codeigniter-and-matchbox-troubles-with-app-routing-part-2.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Анонсирован логотип HTML5</title>
		<link>http://inroot.ru/2011-01/html5-log.html</link>
		<comments>http://inroot.ru/2011-01/html5-log.html#comments</comments>
		<pubDate>Thu, 20 Jan 2011 09:23:27 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[CSS/xHTML]]></category>
		<category><![CDATA[HTML5]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=397</guid>
		<description><![CDATA[Позавчера, твиттер сообщил мне, что W3C анонсировали логотип для HTML5. На сайте www.w3.org этому событию посвящена целая страница, большая и красочная и, самое главное, сверстанная на HTML5! На странице с обзором вы найдете логотипы сопутствующих технологий, презентации, ссылки на сайты, демонстрирующие возможности HTML5, а также массу других интересностей. Прежде всего, вам могут пригодиться варианты баннеров [...]]]></description>
			<content:encoded><![CDATA[<p><img class="post_cover" src="/wp-content/uploads/2011/01/HTML5_Logo_256.png" alt="" title="HTML5_Logo_256" width="128" height="128" class="alignleft size-full wp-image-400" /></p>
<p>Позавчера, твиттер сообщил мне, что W3C анонсировали логотип для HTML5. На сайте <a target="_blank" href="http://www.w3.org/">www.w3.org</a>  этому событию посвящена целая страница, большая и красочная и, самое главное, сверстанная на HTML5!</p>
<p>На <a target="_blank" href="http://www.w3.org/html/logo/">странице с обзором</a> вы найдете логотипы сопутствующих технологий, презентации, ссылки на сайты, демонстрирующие возможности HTML5, а также массу других интересностей. Прежде всего, вам могут пригодиться варианты баннеров с эмблемой HTML5. Возможно, у вас будет желание задействовать их на своем сайте или в каких-нибудь будущих разработках.</p>
<p>Помимо этого, разработчики предлагают вам заказать бесплатные стикеры с логотипами. Для этого необходимо направить им письмо посредством обычной человеческой почты. Я сомневаюсь, что стикеры придут в нашу славную страну, у нас и денежные переводы не всегда приходят, но попробовать вы можете :). Если получится, будет чем похвастаться.</p>
<p>P.S: можно заказать и футболку, но уже за деньги :)</p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-01/html5-log.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PeterHost закрывает партнерскую программу. О как!</title>
		<link>http://inroot.ru/2010-12/peterhost-partnership-is-shit.html</link>
		<comments>http://inroot.ru/2010-12/peterhost-partnership-is-shit.html#comments</comments>
		<pubDate>Thu, 09 Dec 2010 00:24:59 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Вольнодумье]]></category>
		<category><![CDATA[Разное]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=372</guid>
		<description><![CDATA[Не люблю я нытье и жалобы на несправедливую систему и жестокую жизнь но, тут уж не нашел возможности сдержаться. И так, история берет свое начало где-то в середине ноября. У меня есть аккаунт в партнерской программе компании Peterhost. Привлеченных клиентов немного, но есть. Какая-то денежка капает и то приятно. На оплату хостингов, доменов и прочей [...]]]></description>
			<content:encoded><![CDATA[<p>Не люблю я нытье и жалобы на несправедливую систему и жестокую жизнь  но, тут уж не нашел возможности сдержаться.</p>
<p>И так, история берет свое начало где-то в середине ноября. У меня есть аккаунт в партнерской программе компании Peterhost. Привлеченных клиентов немного, но есть. Какая-то денежка капает и то приятно. На оплату хостингов, доменов и прочей электронной утвари хватает.  Собственно, давно не проверял состояние баланса, решил зайти и полюбопытствовать. Вхожу в панель управления, вижу там 1500 русских денег. Через пару недель станет вопрос оплаты хостингов, поэтому, деньги окажутся весьма кстати.</p>
<p><span id="more-372"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Делаю попытку заказать вывод средств на кошелек и вижу сообщение, которое гласит о том, что по техническим причинам, выплаты приостановлены до декабря. Ладно, хорошо, мне не горит, можно подождать. К слову, если верить публикации на сайте, то выплаты приостановили 18 октября.</p>
<p>Неожиданно, пришел декабрь! Первого числа, приходит мне депеша от компании Peterhost, в которой сообщается, как вы думаете что? Ничего хорошего. В рассылке говорится о решении закрыть текущую (не совсем понятно, что значит «текущую») партнерскую программу. И далее следуют комментарии относительно того, что можно сделать со средствами, накопленными на балансе к данному моменту. Далее цитирую текст письма, он же текст <a href="http://peterhost.ru/news/kompaniya-peterhost-zavershaet-partnerskuyu-programmu/">новости на сайте</a>.</p>
<blockquote><p>Денежными средствами, накопленными на партнерском аккаунте к этому моменту, можно воспользоваться одним из следующих способов:</p>
<ul>
<li>заказать услуги хостинга и регистрации доменов;</li>
<li>вывести на Webmoney-кошелек;</li>
<li>вывести на банковский счет физического лица.</li>
</ul>
</blockquote>
<p>Я было обрадовался. Выведу свои копеечки, а дальше делайте, что хотите. Я все равно никогда не придавал большого значения этой партнерской программе. Но не тут то было…</p>
<p>Цитирую дальше:</p>
<blockquote><p>Для подачи заявки на получение денежных средств нужно предоставить следующие документы:</p>
<ul>
<li>подписанный партнером договор;</li>
<li>копию первого разворота паспорта с фото и датой выдачи документа и копию страницы с информацией о прописке;</li>
<li>подписанный партнером отчет на сумму, накопившуюся на партнерском счету к 10 декабря.</li>
</ul>
</blockquote>
<p>Далее следует описание того, как и куда нужно отправить подписанные документы и бла-бла-бла.</p>
<p>Следует ли говорить, что никакого договора я не заключал, впрочем, думаю, как и большинство тех, кто работает в этой партнерке? Думаю, это очевидно.</p>
<p>Конечно, можно поехать в офис, подписать этот злополучный договор. Отсканировать паспорт, принести справку от психиатра, сдать кровь на анализ, сделать рентгеновский снимок и прочее и прочее. Безусловно, полторы тысячи рублей стоят потерянного дня жизни.</p>
<p>Остается один вариант – потратить деньги на услуги Петерхоста. Хотя вот признаюсь, оно мне к черту не нужно. Но выбора не оставили.</p>
<p>Не кажется ли вам, что подобный маневр компании исключительно нечистоплотен? Это ведь банальное выжимание денег из партнеров. Просто нежелание заплатить людям то, что они заработали. Таких, как я, думаю, большинство. Кто будет напрягаться из-за копеечной суммы? Не ошибусь, если скажу, что многие, у кого сумма на балансе еще меньше, просто забудут об этих деньгах. Да, для одного человека 300 рублей не деньги. Но для компании, сумма, которую они зажилят, будет весьма внушительной.</p>
<p>Кстати, тех, кто таки решится заполучить свои кровные, ждет еще один сюрприз! Вот он:</p>
<blockquote><p>
Обращаем внимание на то, что при создании новой заявки сумма к выводу будет рассчитана за вычетом налога на доходы физических лиц. В соответствии с действующим налоговым законодательством России НДФЛ для резидентов РФ составляет 13%, для нерезидентов – 30%. НДФЛ будет направлен в налоговую инспекцию по месту прописки участника программы.
</p></blockquote>
<p>Забавно то как :) Во-первых, Петерхост никогда не брал никаких комиссий на вывод, а тут вдруг решили поиграть в законопослушных товарищей. К слову, отказаться от этой славной услуги никак нельзя. А что, если я сам выплачиваю налоги и не хочу, чтобы это делал кто-то другой? Признаться, я в принципе не имею никакой уверенности в том, что взятый с меня налог дойдет до нужных инстанций. Я даже уверен в обратном. В дополнение к этому, мне кажется, что брать налог с нерезидентов РФ они не имеют права. Хотя, утверждать не буду, так как не юрист ни разу.</p>
<p>Что можно написать в заключении? А ничего хорошего не напишешь. Свинство и только. Казалось бы, крупная компания, можно сказать, лидер на рынке хостинга в России и СНГ, а если судить по поступкам, то шарашкина контора.</p>
<p>Никогда не питал теплых чувств к Петерхосту. В свое время, работал в этой компании и впечатления остались далеко не самые лучшие. Тем не менее, никогда не мог ожидать подобных выходок. Полагал, что они себя уважают.</p>
<blockquote><p>
<strong>Автор:</strong> Мурашов Олег<br />
<strong>Источник:</strong> <a href="http://inroot.ru/">http://inroot.ru/</a>
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2010-12/peterhost-partnership-is-shit.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Java 4-rever. Trailer</title>
		<link>http://inroot.ru/2010-11/java-4-rever-trailer.html</link>
		<comments>http://inroot.ru/2010-11/java-4-rever-trailer.html#comments</comments>
		<pubDate>Fri, 26 Nov 2010 16:53:46 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Разное]]></category>
		<category><![CDATA[Humour]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[OpenSource]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=357</guid>
		<description><![CDATA[Не являюсь ярым поклонником Java, но ролик, который выкладываю, таки взял за душу :) Возможно, вы его уже видели. Я и сам смотрел его очень давно, но вот снова наткнулся и решил опубликовать у себя в блоге. Приятного просмотра :)]]></description>
			<content:encoded><![CDATA[<p>Не являюсь ярым поклонником Java, но ролик, который выкладываю, таки взял за душу :) Возможно, вы его уже видели. Я и сам смотрел его очень давно, но вот снова наткнулся и решил опубликовать у себя в блоге. Приятного просмотра :)</p>
<p><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/8Px-GHPxB4I?fs=1&amp;hl=ru_RU&amp;hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/8Px-GHPxB4I?fs=1&amp;hl=ru_RU&amp;hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2010-11/java-4-rever-trailer.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Апдейт ТИЦ от 28.10.10</title>
		<link>http://inroot.ru/2010-11/upade-cy-281010.html</link>
		<comments>http://inroot.ru/2010-11/upade-cy-281010.html#comments</comments>
		<pubDate>Sun, 31 Oct 2010 22:02:47 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[SEO оптимизация]]></category>
		<category><![CDATA[тИЦ]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=347</guid>
		<description><![CDATA[Месяц назад, я воспроизвел свою первую заметку на тему СЕО :) Правда, грандиозное событие! Конечно, мое творчество ни на что не претендовало. До СЕОшника мне очень далеко и слава Богу, нет никакого желания влезать туда, где я ничегошеньки не понимаю. Тем не менее, факт есть факт. Интерес к СЕО привлекло весьма печальное событие – падение [...]]]></description>
			<content:encoded><![CDATA[<p>Месяц назад, я воспроизвел свою <a href="/2010-09/how-increase-the-number-of-tyc.html">первую заметку на тему СЕО</a> :) Правда, грандиозное событие! Конечно,  мое творчество ни на что не претендовало. До СЕОшника мне очень далеко и слава Богу, нет никакого желания влезать туда, где я ничегошеньки не понимаю. Тем не менее, факт есть факт. </p>
<p>Интерес к СЕО привлекло весьма печальное событие – падение тИЦ на прошлом апдейте. Со 170 попугаев, значение упало до 140. Конечно, сразу пришлось понизить цены на ссылки в <a href="http://www.sape.ru/r.sJTyfWRIVV.php" target="_blank">Sape</a>. Доходы не сильно упали, но было неприятно. Больше всего я опасался того, что падения продолжаться на следующих апдейтах. И вот, свершилось чудо! Мои мытарства, нацеленные на повышение, но прежде всего, на удержание показателей, увенчались успехов. Апдейт, прошедший несколько дней назад, вернул значение счетчика, подарив мне 30 заветных попугаев.</p>
<p><span id="more-347"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Признаться, я не уверен в том, что это моих рук дело. Количество бэков, можно сказать, абсолютно не изменилось. Возможно, какую-то роль сыграла закупка ссылок в <a href="http://www.sape.ru/r.sJTyfWRIVV.php" target="_blank">Сапе</a>. Старался сильно не жлобиться и больше ориентироваться на показатели донора, нежели на ценник. Тем не менее, за месяц оставил порядка 150 ссылок в блогах, хотя почти все они закрыты через <tt>rel='external nofollow'</tt>. Прописал адрес сайта в подписях на форумах, социальных сетях и других сервисах. Думаю, что продолжу работать в этом направлении, глядишь, будет от этого польза.</p>
<p>Надеюсь, минувший апдейт был также хорош и для вас. Успехов вам и всяческих благ!</p>
<blockquote><p>
<strong>Автор:</strong> Мурашов Олег<br />
<strong>Источник:</strong> <a href="http://inroot.ru/">http://inroot.ru/</a>
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2010-11/upade-cy-281010.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CodeIgniter и Matchbox: проблемы роутинга приложения</title>
		<link>http://inroot.ru/2010-10/codeigniter-and-matchbox-troubles-with-application-routing.html</link>
		<comments>http://inroot.ru/2010-10/codeigniter-and-matchbox-troubles-with-application-routing.html#comments</comments>
		<pubDate>Fri, 01 Oct 2010 09:50:35 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Matchbox]]></category>
		<category><![CDATA[Модульность CodeIgniter]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=330</guid>
		<description><![CDATA[Давеча, намедни, решил написать небольшую CMS для своих собственных нужды и, быть может, если все это увенчается успехом, для некоторых коммерческих заказов. В качестве фреймворка, как мне показалось, для этих целей наиболее подойдет Codeigniter. Прост, быстр и достаточно удобен. Всем, что мне требуется, он вполне располагает. Чего нет, не беда, люди мы не гордые, допишем [...]]]></description>
			<content:encoded><![CDATA[<p><img class="post_cover" src="http://inroot.ru/wp-content/uploads/2010/10/ci_logo_flame-150x150.jpg" alt="CodeIgniter и Matchbox: проблемы роутинга приложения" title="ci_logo_flame" width="150" height="150" class="alignleft size-thumbnail wp-image-387" /></p>
<p>Давеча, намедни, решил написать небольшую CMS для своих собственных нужды и, быть может, если все это увенчается успехом, для некоторых коммерческих заказов. В качестве фреймворка, как мне показалось, для этих целей наиболее подойдет <strong>Codeigniter</strong>. Прост, быстр и достаточно удобен. Всем, что мне требуется, он вполне располагает. Чего нет, не беда, люди мы не гордые, допишем и сами.</p>
<p>Первое, чего хотелось добиться – <strong>модульной структуры приложения</strong>. Увы, CI, насколько я его знаю, сам по себе на модульность никак не рассчитан.  Во всяком случае в той степени, в какой мне нужно.</p>
<p>Тоже не проблема. Есть библиотеки, которые доводят данный фреймворк до нужной кондиции. Одна из таких &#8211; <strong>Matchbox</strong>.</p>
<p><span id="more-330"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Качаем библиотеку <a href="http://codeigniter.com/wiki/Matchbox/" target="_blank">отсюда</a>. Устанавливаем простой распаковкой файлов. Matchbox ничего не заменяет собой физически, поэтому можно не бояться, что какие-то ваши наработки затрутся.</p>
<p>Первое, что меня расстроило – отсутствие какой бы то ни было документации. Все, что я нашел, не считая различных обсуждений в форумах, что документацией ну никак не является, это мануал по установке (ссылка выше), в котором есть пару абзацев текста на тему того, как всем этим пользоваться. В принципе, мне этого достаточно, во всяком случае, чтобы начать.</p>
<p>И так, после установки, в директории <tt>/application/</tt> у нас появляется директория с именем /modules. Собственно, это и есть та самая модульная структура.  Чтобы понять структуру модуля, достаточно посмотреть, как реализован тот, что изначально ставится с Matchbox &#8211; <tt>/application/modules/matchbox</tt>. </p>
<p>Я сразу создал свой, называющийся <tt>/user</tt>. Предположительно, данный модуль будет отвечать на все вопросы по работе с пользовательской учетной записью: регистрация, авторизация, профиль пользователя и так далее.</p>
<p>Делаем контроллер, пока просто для теста:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> User <span style="color: #000000; font-weight: bold;">extends</span> Controller
<span style="color: #009900;">&#123;</span>
    <span style="color: #009933; font-style: italic;">/**
     * 
     * @access public
     * @return void
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        parent<span style="color: #339933;">::</span>__construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Index method
&nbsp;
     * @access public
     * @return void
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #009900; font-weight: bold;">__METHOD__</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Login method
&nbsp;
     * @access public
     * @return void
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> login<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #009900; font-weight: bold;">__METHOD__</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * User profile handler
&nbsp;
     * @access public
     * @return void
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> profile<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #009900; font-weight: bold;">__METHOD__</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Теперь попробуем вызвать метод <tt>User::login()</tt> из браузера. Для этого нужно будет обратиться по адресу (если вы используете ЧПУ) <tt>http://localhost/user/user/login/</tt></p>
<p><strong>Request URI имеет три сегмента</strong>. Первый сегмент передает имя модуля, к которому обращаемся, второй – имя контроллера, а третий – имя метода контроллера.</p>
<p>Дело обстоит именно так, потому, что <strong>Matchbox</strong> позволяет содержать более одного контроллера в одном модуле. Ну и славно! Но, мне определенно не нравится такой способ вызова нужного мне метода. Во-первых, очень длинный url, во вторых, в данном конкретном случае имеется два одинаковых сегмента, что выглядит достаточно странно. Значит нужно настроить роутинг, &#8211; подумал я. Тут начинается веселье.</p>
<p>Во-первых, как я уже сказал, адекватной документации по Matchbox я не нашел. Как настраивать роутинг у модулей, что называется, догадайтесь как-нибудь сами. И я догадался, но через сутки, после того, как перечитал весь код библиотеки, отвечающей за роутинг. Но, по порядку&#8230;</p>
<p>Первое, что попробовал сделать – задать правила роутинга в файле <tt>/application/config/routes.php</tt>. Чего я там только не писал. Изворачивался и так и этак, даже документацию по регулярным выражениям почитать успел, но желаемого эффекта ноль.</p>
<p>Поковырявшись в коде, я понял, что для достижения желаемого эффекта нужно писать <strong>два набора правил роутинга</strong>. Первый пишется в <tt>/application/config/routes.php</tt>, а второй, в файл, локальный для модуля routes.php. Чтобы иметь возможность дергать метод <tt>User::login()</tt> нужно написать следующее:</p>
<p><b>Файл /application/config/routes.php</b></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$route</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'user/login'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'user/user/login'</span><span style="color: #339933;">;</span></pre></div></div>

<p><b>Файл /application/modules/user/config/routes.php</b></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$route</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'login'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'user/login'</span><span style="color: #339933;">;</span></pre></div></div>

<p>При таком раскладе все работает. Отчасти логичный, но, в тоже время, странный подход. Ладно, человек – существо функциональное и к адаптации пригожее, поэтому будем делать так, как просят.</p>
<p>Но, а что, если нам нужно вызвать метод <tt>User::profile()</tt> по адресу <tt>http://localhost/profile/</tt>? Вот тут я почти вышел в астрал.  Пляски с правилами роутинга были еще более озорными и увлекательными. Я достал все шаманские бубны, что у меня были. Прыгал через костер, общался с духами предков, взывал к микрокосму. Неа, не помогло… Принимаем  сто грамм для храбрости и айда снова код читать.</p>
<p>В итоге выясняется, что <strong>Matchbox</strong> вообще никак не читает глобальных правил роутинга. Работает он по весьма странной схеме. Прежде чем начинается разбор глобальных правил, библиотека проверяет, имеется ли у нее модуль, имя которого содержится в первом сегменте. То есть, первый сегмент URI всегда должен содержать имя физически существующего модуля. Если модуль есть, читаются правила роутинга, локальные для этого модуля. Дальнейшая обработка отдается в руки нативному роутеру CI, который читает уже свои правила (глобальные) и рулит приложением привычным для него образом. А если модуля нет, то Matchbox снимает с себя все обязательства и опять же передает управление нативному роутеру. И что там в правилах написано – дело десятой важности.</p>
<p>То есть нужно заставить Matchbox хоть как-то реагировать на глобальный роутинг. Я не придумал ничего лучше, чем читать правила из <tt>/application/config/routes.php</tt> до того момента, как Matchbox начинает свои бесовские пляски. Не долго думая, как же это сделать, я просто скопировал метод <tt>Router::_parse_routes()</tt>, переименовал его в <tt>MY_Router::_mb_parse_routes()</tt> и убрал лишнее.</p>
<p>Получилось вот так:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
</pre></td><td class="code"><pre class="php" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> _mb_parse_routes<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Turn the segment array into a URI string</span>
        <span style="color: #000088;">$uri</span> <span style="color: #339933;">=</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">uri</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">segments</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Is there a literal match?  If so we're done</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">routes</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$uri</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">uri</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">segments</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">routes</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$uri</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
            <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Loop through the route array looking for wild-cards</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">routes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$val</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// Convert wild-cards to RegEx</span>
            <span style="color: #000088;">$key</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">':any'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'.+'</span><span style="color: #339933;">,</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">':num'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'[0-9]+'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #666666; font-style: italic;">// Does the RegEx match?</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'#^'</span><span style="color: #339933;">.</span><span style="color: #000088;">$key</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'$#'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$uri</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>           
                <span style="color: #666666; font-style: italic;">// Do we have a back-reference?</span>
                <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$val</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'$'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">FALSE</span> AND <span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'('</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                    <span style="color: #000088;">$val</span> <span style="color: #339933;">=</span> <span style="color: #990000;">preg_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'#^'</span><span style="color: #339933;">.</span><span style="color: #000088;">$key</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'$#'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$val</span><span style="color: #339933;">,</span> <span style="color: #000088;">$uri</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
&nbsp;
                <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">uri</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">segments</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$val</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>        
                <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Я просто изменяю URI в соответствии с глобальными правилами роутинга и подсовываю результат Matchbox’у, мол так и было.</p>
<p>Вызов <tt>MY_Router::_mb_parse_routes()</tt> вписываем таким вот образом (у меня нужный фрагмент начинается на <strong>279 строке</strong> файла <tt><b>/application/libraries/MT_Router.php</b></tt>):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;">		<span style="color: #666666; font-style: italic;">// {{{ Matchbox</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">uri</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">segments</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #666666; font-style: italic;">// Added by 0mm</span>
		    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_mb_parse_routes<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000088;">$segments</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">uri</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">segments</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$module</span>   <span style="color: #339933;">=</span> <span style="color: #000088;">$segments</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/'</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Понимаю, что решение далеко от оптимального. Прежде всего, мы почти полностью дублируем метод <tt>Router::_parse_routes()</tt>, а это уже плохо. Также мы решаем проблему только для достаточно частного случая. Но, увы, у меня нет времени изобретать что-то более адекватное. Чуть позже, безусловно, займусь этим вопросом. Пока мне требуется решить именно эту проблему и, так или иначе, я ее решил…</p>
<p>В любом случае, вы теперь знаете, в каком направление махать лопатой. Если у вас будет время и вы таки найдете более изящную заплатку для Matchbox, буду благодарен, если поделитесь наработками.</p>
<p>Да прибудет с вами удача!</p>
<blockquote><p>
<strong>Автор:</strong> Мурашов Олег<br />
<strong>Источник:</strong> <a href="http://inroot.ru/">http://inroot.ru/</a>
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2010-10/codeigniter-and-matchbox-troubles-with-application-routing.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

