<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.1" -->
<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/"
	>

<channel>
	<title>Всякие интересные штучки для WEB-разработчика</title>
	<link>http://ilovethat.info/blog</link>
	<description>блог о технологиях web-разработки</description>
	<pubDate>Wed, 06 Aug 2008 23:56:49 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.1</generator>
	<language>en</language>
			<item>
		<title>Опции CFLAGS FreeBSD</title>
		<link>http://ilovethat.info/blog/archives/67</link>
		<comments>http://ilovethat.info/blog/archives/67#comments</comments>
		<pubDate>Wed, 06 Aug 2008 23:56:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[FreeBSD/Linux]]></category>

		<guid isPermaLink="false">http://ilovethat.info/blog/archives/67</guid>
		<description><![CDATA[Опции CFLAGS FreeBSD:
1. &#8220;-О&#8221; Компилятор пытается сократить как размер кода, так и время его выполнения. И при этом не выполняет модификаций, которые могут затруднить отладку программы. Включает опции -fno-optimize-size, -fdefer-pop, -fthread-jumps, -fguess-branch-probability, -cprop-registers и-fdelayed-branch. Флаг -fomit-frame-pointer устанавливается только если применяемый отладчик способен работать без использования регистра указателя кадра стека.
2. “-О0″ Действует по умолчанию. Отключает любые [...]]]></description>
			<content:encoded><![CDATA[<p>Опции CFLAGS FreeBSD:<br />
1. &#8220;-О&#8221; Компилятор пытается сократить как размер кода, так и время его выполнения. И при этом не выполняет модификаций, которые могут затруднить отладку программы. Включает опции -fno-optimize-size, -fdefer-pop, -fthread-jumps, -fguess-branch-probability, -cprop-registers и-fdelayed-branch. Флаг -fomit-frame-pointer устанавливается только если применяемый отладчик способен работать без использования регистра указателя кадра стека.</p>
<p>2. “-О0″ Действует по умолчанию. Отключает любые оптимизации размера кода и устанавливает флаг -fno-merge-constants.</p>
<p>3. “-О1″ То же, что -О</p>
<p>4. “-О2″ На этом уровне применяются все виды оптимизации, которые не требуют вычисления оптимального выбора между размером и скоростью кода. Кроме флагов, устанавливаемых при -О, дополнительно задействует следующие опции -foptimize-sibling-calls, -fcse-follow-jumps, -fcse-skip-blocks, -fgcae, -expensive-optimizations, -fstrength-reduce, -frerun-cse-after-loop, -frerun-loop-opt, -fcaller-aaves, -fforce-mem, -fpeephole2, -fshedule-insns, -fshedule-insns-after-reload, -fregmove, -fstrict-aliasing, -fdelete-null-pointer-checks и -freorder-blocka. Этот уровень оптимизации не разворачивает циклы, не выполняет оптимизацию подстановок (inlining) и переназначение регистров.</p>
<p>5. “-О3″ В дополнение к опциям, включаемым при -О2, устанавливает также -finline-functions и -frename-registers.</p>
<p>6. “-Os” Оптимизирует размер программы. Устанавливает все опции, действующие при -О3. Устанавливает опции -falign-loops, -falign-jumps, -falign-labels и -falign-functions с параметром =1, что не допускает вставку пустого пространства для применения выравнивания.</p>
<p>Выдернуто из комментариев на http://www.lissyara.su/?id=1326 .</p>
]]></content:encoded>
			<wfw:commentRss>http://ilovethat.info/blog/archives/67/feed</wfw:commentRss>
		</item>
		<item>
		<title>Как удалять старые бэкапы?</title>
		<link>http://ilovethat.info/blog/archives/65</link>
		<comments>http://ilovethat.info/blog/archives/65#comments</comments>
		<pubDate>Wed, 06 Aug 2008 23:55:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[FreeBSD/Linux]]></category>

		<guid isPermaLink="false">http://ilovethat.info/blog/archives/65</guid>
		<description><![CDATA[один из способов:
/usr/bin/find /var/backup/ -name “*” -mtime +10 -print &#124; /usr/bin/xargs rm -rf
Итого: удаляем из папки /var/backup/ все то, что были изменено более 10 дней назад.
]]></description>
			<content:encoded><![CDATA[<p>один из способов:</p>
<p><b>/usr/bin/find /var/backup/ -name “*” -mtime +10 -print | /usr/bin/xargs rm -rf</b></p>
<p>Итого: удаляем из папки /var/backup/ все то, что были изменено более 10 дней назад.</p>
]]></content:encoded>
			<wfw:commentRss>http://ilovethat.info/blog/archives/65/feed</wfw:commentRss>
		</item>
		<item>
		<title>Шпаргалка по Unix (FreeBSD, Linux and etc…)</title>
		<link>http://ilovethat.info/blog/archives/63</link>
		<comments>http://ilovethat.info/blog/archives/63#comments</comments>
		<pubDate>Wed, 06 Aug 2008 23:52:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[FreeBSD/Linux]]></category>

		<guid isPermaLink="false">http://ilovethat.info/blog/archives/63</guid>
		<description><![CDATA[Такой… Мини-справочник для начинающих.
http://cb.vu/unixtoolbox.xhtml
Ну и в PDF: http://cb.vu/unixtoolbox.pdf
]]></description>
			<content:encoded><![CDATA[<p>Такой… Мини-справочник для начинающих.</p>
<p>http://cb.vu/unixtoolbox.xhtml</p>
<p>Ну и в PDF: http://cb.vu/unixtoolbox.pdf</p>
]]></content:encoded>
			<wfw:commentRss>http://ilovethat.info/blog/archives/63/feed</wfw:commentRss>
		</item>
		<item>
		<title>Finding out largest tables on MySQL Server</title>
		<link>http://ilovethat.info/blog/archives/61</link>
		<comments>http://ilovethat.info/blog/archives/61#comments</comments>
		<pubDate>Wed, 06 Aug 2008 22:32:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Mysql]]></category>

		<guid isPermaLink="false">http://ilovethat.info/blog/archives/61</guid>
		<description><![CDATA[Finding largest tables on MySQL instance is no brainier in MySQL 5.0+ thanks to Information Schema but I still wanted to post little query I use for the purpose so I can easily find it later, plus it is quite handy in a way it presents information:
SELECT concat(table_schema,'.',table_name),concat(round(table_rows/1000000,2),'M') rows,concat(round(data_length/(1024*1024*1024),2),'G') DATA,concat(round(index_length/(1024*1024*1024),2),'G') idx,concat(round((data_length+index_length)/(1024*1024*1024),2),'G') total_size,round(index_length/data_length,2) idxfrac FROM information_schema.TABLES [...]]]></description>
			<content:encoded><![CDATA[<p>Finding largest tables on MySQL instance is no brainier in MySQL 5.0+ thanks to Information Schema but I still wanted to post little query I use for the purpose so I can easily find it later, plus it is quite handy in a way it presents information:</p>
<p><code>SELECT concat(table_schema,'.',table_name),concat(round(table_rows/1000000,2),'M') rows,concat(round(data_length/(1024*1024*1024),2),'G') DATA,concat(round(index_length/(1024*1024*1024),2),'G') idx,concat(round((data_length+index_length)/(1024*1024*1024),2),'G') total_size,round(index_length/data_length,2) idxfrac FROM information_schema.TABLES ORDER BY data_length+index_length DESC LIMIT 10;</code></p>
<p>http://www.mysqlperformanceblog.com/2008/02/04/finding-out-largest-tables-on-mysql-server/</p>
]]></content:encoded>
			<wfw:commentRss>http://ilovethat.info/blog/archives/61/feed</wfw:commentRss>
		</item>
		<item>
		<title>Как русифицировать консоль во FreeBSD 7.0</title>
		<link>http://ilovethat.info/blog/archives/59</link>
		<comments>http://ilovethat.info/blog/archives/59#comments</comments>
		<pubDate>Wed, 06 Aug 2008 22:21:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[FreeBSD/Linux]]></category>

		<guid isPermaLink="false">http://ilovethat.info/blog/archives/59</guid>
		<description><![CDATA[Bash: $HOME/.inputrc
set convert-meta off
set input-meta on
set output-meta on
$HOME/.bash_profile
export CHARSET=CP1251
export MM_CHARSET=CP1251
export LANG=ru_RU.CP1251
export LC_ALL=ru_RU.CP1251
Tcsh[Csh] $HOME/.login
setenv CHARSET CP1251
setenv MM_CHARSET CP1251
setenv LANG ru_RU.CP1251
setenv LC_ALL ru_RU.CP1251
]]></description>
			<content:encoded><![CDATA[<p>Bash: $HOME/.inputrc<br />
set convert-meta off<br />
set input-meta on<br />
set output-meta on</p>
<p>$HOME/.bash_profile<br />
export CHARSET=CP1251<br />
export MM_CHARSET=CP1251<br />
export LANG=ru_RU.CP1251<br />
export LC_ALL=ru_RU.CP1251</p>
<p>Tcsh[Csh] $HOME/.login<br />
setenv CHARSET CP1251<br />
setenv MM_CHARSET CP1251<br />
setenv LANG ru_RU.CP1251<br />
setenv LC_ALL ru_RU.CP1251</p>
]]></content:encoded>
			<wfw:commentRss>http://ilovethat.info/blog/archives/59/feed</wfw:commentRss>
		</item>
		<item>
		<title>Pentium D – совместимость</title>
		<link>http://ilovethat.info/blog/archives/57</link>
		<comments>http://ilovethat.info/blog/archives/57#comments</comments>
		<pubDate>Wed, 23 Jul 2008 15:51:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Hardware]]></category>

		<guid isPermaLink="false">http://ilovethat.info/blog/archives/57</guid>
		<description><![CDATA[Совместимость процессоров PentiumD с LGA775 материнскими платами зависит от двух вещей - чипсета и схемы питания процессора.
Чипсеты, с которыми Pentium D могут работать - Intel 865, 945, 955, 965, 975, E7230, nVidia nForce 4 Intel Edition, ATI XPRESS 200, VIA PT880, P4M800, SiS 656 (Cписок не претендует на абсолютную полноту касательно чипсетов сторонних производителей.)
Чипсеты, с [...]]]></description>
			<content:encoded><![CDATA[<p>Совместимость процессоров PentiumD с LGA775 материнскими платами зависит от двух вещей - чипсета и схемы питания процессора.</p>
<p>Чипсеты, с которыми Pentium D могут работать - Intel 865, 945, 955, 965, 975, E7230, nVidia nForce 4 Intel Edition, ATI XPRESS 200, VIA PT880, P4M800, SiS 656 (Cписок не претендует на абсолютную полноту касательно чипсетов сторонних производителей.)</p>
<p><strong>Чипсеты, с которыми Pentium D работать принципиально не могут (ни в одной плате!) – Intel 910, 915, 925, E7221.</strong></p>
<p>Pentium D бывает двух принципиально отличающихся разновидностей – PentiumD 8XX («восьмисотой серии») на ядре Smithfield и Pentium D 9XX («девятисотой серии») на ядре Presler. У этих ядер разные требования к питанию, и не во всех материнской платах, где заработает «восьмисотый» Pentium D, заработает и «девятисотый».</p>
<p>По умолчанию, формально заявленная поддержка Pentium D означает поддержку ядра Smithfield, т.е. «восьмисотой» серии, если явно не сказано иное (например, упомянуто ядро Presler) , однако, подавляющее большинство плат на чипсетах Intel 945/955/975, включая все модели популярных семейств ASUS P5LD2/P5WD2(всех модификаций) работают со всеми Pentium D, включая все «девятисотые».</p>
<p>Большинство плат, поддерживающих «восьмисотые», но не поддерживающих «девятисотые» Pentium D, сделаны на чипсетах i865, nVidia nForce4 SLI Intel Edition, SiS 656 и на момент написания FAQ(июль 2006 года) постепенно исчезают из продажи. Платы на nForce4 SLI Intel Edition к тому же не поддерживают Pentium D 805 и Pentium D 820 - это индивидуальная особенность чипсета</p>
<p>Процессоры Pentium Extreme Edition 840 работают в материнских платах на чипсетах Intel 955/975 и в некоторых платах на чипсетах сторонних производителей. Процессоры Pentium Extreme Edition 955/965 работают только в платах на чипсете Intel 975 и в некоторых платах на чипсетах сторонних производителей. Ни один процессор Intel Pentium Extreme Edition не работает в платах на чипсете Intel 945.</p>
<p>Помните, что наиболее достоверную информацию о совместимости материнской платы и процессора можно всегда почерпнуть из «списка поддерживаемых процессоров» («CPU Support List») с интернет-сайта производителя материнской платы.</p>
]]></content:encoded>
			<wfw:commentRss>http://ilovethat.info/blog/archives/57/feed</wfw:commentRss>
		</item>
		<item>
		<title>FreeBSD: Эмуляция проблемных каналов</title>
		<link>http://ilovethat.info/blog/archives/55</link>
		<comments>http://ilovethat.info/blog/archives/55#comments</comments>
		<pubDate>Thu, 17 Jul 2008 07:18:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[FreeBSD/Linux]]></category>

		<category><![CDATA[FreeBSD]]></category>

		<guid isPermaLink="false">http://ilovethat.info/blog/archives/55</guid>
		<description><![CDATA[В файрволе FreeBSD (IPFW) есть довольно редкая встроенная фича - возможность эмуляции потери пакетов, задержки, полосы пропускания и др. параметров связи.
Эта поддержка включена в подсистему TRAFFIC SHAPER (DUMMYNET).
Настраивается следующим образом:
   1. Создаем &#8220;канал&#8221; (pipe) с необходимыми характеристиками:
      ipfw pipe
 config plr  delay  bw 300Kbit/s queue 128Kbytes [...]]]></description>
			<content:encoded><![CDATA[<p>В файрволе FreeBSD (IPFW) есть довольно редкая встроенная фича - возможность эмуляции потери пакетов, задержки, полосы пропускания и др. параметров связи.</p>
<p>Эта поддержка включена в подсистему TRAFFIC SHAPER (DUMMYNET).</p>
<p>Настраивается следующим образом:</p>
<p>   1. Создаем &#8220;канал&#8221; (pipe) с необходимыми характеристиками:<br />
      ipfw pipe
<pipe-number> config plr <от 0 до 1> delay <в миллисекундах> bw 300Kbit/s queue 128Kbytes [red] [noerror]</p>
<p>   2. Дальше выбираем трафик, который в этот канал будет попадать:<br />
      ipfw add <rule-number> pipe
<pipe-number> <rule></p>
<p>   3. Просмотр конфигурации канала: ipfw pipe show
<pipe-number>
<p>Пример (эмуляция 30% потерь всех пакетов от 192.168.11.40):<br />
ipfw pipe 10 config plr 0.3<br />
ipfw add 10 pipe 10 ip from 192.168.11.40 to any<br />
ipfw pipe show<br />
ipfw show</p>
<p>Подробнее в man ipfw</p>
<p>Область применения данной технологии: шейпер (ограничение скорости по ip-адресам, протоколам), тестирование сетевых решения и программных продуктов в условиях, приближенных к реальным проблемным (или забитым) каналам.</p>
]]></content:encoded>
			<wfw:commentRss>http://ilovethat.info/blog/archives/55/feed</wfw:commentRss>
		</item>
		<item>
		<title>FreeBSD: Средства мониторинга</title>
		<link>http://ilovethat.info/blog/archives/53</link>
		<comments>http://ilovethat.info/blog/archives/53#comments</comments>
		<pubDate>Thu, 17 Jul 2008 07:08:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[FreeBSD/Linux]]></category>

		<guid isPermaLink="false">http://ilovethat.info/blog/archives/53</guid>
		<description><![CDATA[Во FreeBSD существует огромное количество средств для получения информации о функционировании системы. Однако некоторые из них спрятаны немного нетривиально.
   1. Информация о дисках
         1. mount - показывает смонтированные подразделы и флаги из монтирования
         2. df - показывает [...]]]></description>
			<content:encoded><![CDATA[<p>Во FreeBSD существует огромное количество средств для получения информации о функционировании системы. Однако некоторые из них спрятаны немного нетривиально.</p>
<p>   1. Информация о дисках</p>
<p>         1. mount - показывает смонтированные подразделы и флаги из монтирования<br />
         2. df - показывает смонтированные подразделы, их размер и свободное место на них<br />
         3. fdisk /dev/ad0 - показывает информацию о диске ad0 и разделах на нем<br />
         4. disklabel /dev/ad0s1 - показывает список подразделов в первом разделе диска ad0<br />
         5. swapinfo - показывает список подразделов свопинга на дисках и их использование<br />
         6. fstat - показывает список открытых файлов (имена файлов не выводятся)<br />
         7. pstat -f - выводит список открытых файлов (имена файлов не выводятся)<br />
         8. systat -vmstat n - каждые n секунд выводит количество транзакций с диском в секунду, объем записанных/считанных данных на диск в секунду, средний размер транзакции и процент времени в течение которого диск был занят работой.<br />
         9. iostat - выводит информацию, аналогичную systat -vmstat, но не выводит занятости диска по времени и может выводить среднюю статистику с момента загрузки.<br />
        10. vmstat - выводит количество операций на диске в секунду<br />
        11. /stand/sysinstall - можно посмотреть и изменить разметку диска и монтирование<br />
        12. less /etc/fstab - таблица монтирования при загрузке</p>
<p>   2. Информация о процессоре и памяти</p>
<p>         1. systat -vmstat n - вывод показателей загрузки (number of jobs in the run queue averaged over 1, 5 and 15 min), состояния памяти (в страницах), количества процессов в группах, количество вызовов специальных функций ядра (traps, interrupts, system calls, network software interrupts), использование процессора, трансляции имен, активность свопа, прерывания, а также информацию по использованию диска (см)<br />
         2. top - аналогичная информация в сокращенном виде + использование памяти и свопа в мегабайтах, список процессов, отсортированных по использованию процессора.<br />
         3. ps afx - список запущенных процессов и время процессора на каждый</p>
<p>   3. Информация о сети</p>
<p>         1. ifconfig - список сетевых интерфейсов с ip-адресами, масками, mac-адресами, типами карт и их статусами (названия карточек можно посмотреть в файле конфигурации ядра)<br />
         2. systat -ifstat n - объем трафика за n секунд на всех сетевых интерфейсах<br />
         3. netstat - вывод активных сетевых соединений (сокетов)<br />
         4. systat -netstat n - аналог netstat в реальном времени<br />
         5. systat -ip n - таблица IP-пакетов и ошибок по типам за n секунд<br />
         6. systat -tcp n - таблица TCP-пакетов и ошибок по типам за n секунд<br />
         7. systat -icmp n - таблица ICMP-пакетов и ошибок по типам за n секунд<br />
         8. netstat -ibt - список интерфейсов, разбитых по ip-адресам (!) с объемом трафика на каждом, количеством ошибок, коллизий, значением watchdog-таймера<br />
         9. netstat -r - таблица маршрутизации<br />
        10. arp -a - таблица ARP<br />
        11. tcpdump -i rl0 host 192.168.61.20 and port 80 - сниффер пакетов на интерфейсе rl0, фильтрующий пакеты, содержащие адрес 192.168.61.20 и порт 80<br />
        12. trafshow -i rl0 - программа для сортировки и вывода сетевых потоков (устанавливается дополнительно пакетом или из портов)</p>
<p>   4. Службы времени</p>
<p>         1. date - выводит текущее время и дату<br />
         2. w - выводит, сколько времени назад система загрузилась и залогиненных пользователей<br />
         3. last - выводит историю перезагрузок и входов пользователей</p>
]]></content:encoded>
			<wfw:commentRss>http://ilovethat.info/blog/archives/53/feed</wfw:commentRss>
		</item>
		<item>
		<title>Одновременный запуск некольких FireFox с разными профилями</title>
		<link>http://ilovethat.info/blog/archives/51</link>
		<comments>http://ilovethat.info/blog/archives/51#comments</comments>
		<pubDate>Fri, 11 Jul 2008 18:27:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Soft/Tools]]></category>

		<category><![CDATA[firefox profile]]></category>

		<guid isPermaLink="false">http://ilovethat.info/blog/archives/51</guid>
		<description><![CDATA[Известно, что в Firefox реализована поддержка нескольких пользовательских профилей. Ими можно распоряжаться как угодно: от разделения для каждого пользователя, например когда под одной учетной записью в Windows работают несколько пользователей или выделить отдельный профиль для ребенка. Также можно использовать профили для тестирования или написания собственных расширений.
Лично у меня для разработки и отладки существует отдельный профиль, [...]]]></description>
			<content:encoded><![CDATA[<p>Известно, что в Firefox реализована поддержка нескольких пользовательских профилей. Ими можно распоряжаться как угодно: от разделения для каждого пользователя, например когда под одной учетной записью в Windows работают несколько пользователей или выделить отдельный профиль для ребенка. Также можно использовать профили для тестирования или написания собственных расширений.<span id="more-7"></span></p>
<p>Лично у меня для разработки и отладки существует отдельный профиль, в котором собраны специальные расширения для разработки и отладки кода и дизайна сайтов и расширений. Они занимают лишнюю память и тормозят браузер в процессе серфинга по сети. <a href="http://ilovethat.info/blog/archives/51#more-51" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://ilovethat.info/blog/archives/51/feed</wfw:commentRss>
		</item>
		<item>
		<title>Tricky Tricky Refcounts…</title>
		<link>http://ilovethat.info/blog/archives/49</link>
		<comments>http://ilovethat.info/blog/archives/49#comments</comments>
		<pubDate>Fri, 11 Jul 2008 15:46:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Theory]]></category>

		<guid isPermaLink="false">http://ilovethat.info/blog/archives/49</guid>
		<description><![CDATA[Occasionally a PHP engineer reports this prolem:
Example Code:————$my_arr = array(1,2,3);foreach ($my_arr as &#38;$val) {    var_dump($val);}foreach ($my_arr as $val) {    var_dump($val);}Expected Output:———int(1)int(2)int(3)int(1)int(2)int(3)Actual Output:——-int(1)int(2)int(3)int(1)int(2)int(2)
The confusion comes from the expectation that the second loop will print the last element of the array as int(3) rather than int(2).  The initial reaction is usally “this is a PHP bug”, but [...]]]></description>
			<content:encoded><![CDATA[<p>Occasionally a PHP engineer reports this prolem:</p>
<p><span style="font-family: Courier">Example Code:</span><br style="font-family: Courier" /><span style="font-family: Courier">————</span><br style="font-family: Courier" /><span style="font-family: Courier">$my_arr = array(1,2,3);</span><br style="font-family: Courier" /><span style="font-family: Courier">foreach ($my_arr as &amp;$val) {</span><br style="font-family: Courier" /><span style="font-family: Courier">    var_dump($val);</span><br style="font-family: Courier" /><span style="font-family: Courier">}</span><br style="font-family: Courier" /><span style="font-family: Courier">foreach ($my_arr as $val) {</span><br style="font-family: Courier" /><span style="font-family: Courier">    var_dump($val);</span><br style="font-family: Courier" /><span style="font-family: Courier">}</span><br style="font-family: Courier" /><br style="font-family: Courier" /><br style="font-family: Courier" /><span style="font-family: Courier">Expected Output:</span><br style="font-family: Courier" /><span style="font-family: Courier">———</span><br style="font-family: Courier" /><span style="font-family: Courier">int(1)</span><br style="font-family: Courier" /><span style="font-family: Courier">int(2)</span><br style="font-family: Courier" /><span style="font-family: Courier">int(3)</span><br style="font-family: Courier" /><span style="font-family: Courier">int(1)</span><br style="font-family: Courier" /><span style="font-family: Courier">int(2)</span><br style="font-family: Courier" /><span style="font-family: Courier; font-weight: bold">int(3)</span><br style="font-family: Courier" /><br style="font-family: Courier" /><span style="font-family: Courier">Actual Output:</span><br style="font-family: Courier" /><span style="font-family: Courier">——-</span><br style="font-family: Courier" /><span style="font-family: Courier">int(1)</span><br style="font-family: Courier" /><span style="font-family: Courier">int(2)</span><br style="font-family: Courier" /><span style="font-family: Courier">int(3)</span><br style="font-family: Courier" /><span style="font-family: Courier">int(1)</span><br style="font-family: Courier" /><span style="font-family: Courier">int(2)</span><br style="font-family: Courier" /><span style="font-family: Courier; font-weight: bold">int(2)</span><br style="font-family: Courier" /><br />
The confusion comes from the expectation that the second loop will print the last element of the array as int(3) rather than int(2).  The initial reaction is usally “this is a PHP bug”, but it really isn’t.  There are two key aspects to this code to watch out for; 1) The scope of foreach variables is not limited to the foreach block. 2) Foreach loops do not unset foreach variables at the start of the block.</p>
<p>With this in mind we can see that at the end of the first loop, $val is a reference to the last element of $my_arr.  Each iteration over the foreach loop can be thought of as an assignment operation, in this case by reference:</p>
<p><span style="font-family: Courier">$val = &amp;$my_arr[0]</span><br style="font-family: Courier" /><span style="font-family: Courier">$val = &amp;$my_arr[1]</span><br style="font-family: Courier" /><span style="font-family: Courier">$val = &amp;$my_arr[2]<br />
// last iteration $val is a reference to $my_arr[2]</span><br style="font-family: Courier" /><br />
As we step through each iteration of the second foreach loop we see the assignments of $val to each element of the $my_arr (assigned by value this time).</p>
<p><span style="font-family: Courier">$val = $my_arr[0]</span><br style="font-family: Courier" /><span style="font-family: Courier">$val = $my_arr[1]</span><br style="font-family: Courier" /><span style="font-family: Courier">$val = $my_arr[2]</span><br style="font-family: Courier" /><br />
But if we you recall $val is really a reference to the last element of $my_arr because it carries over from the first foreach loop, so the actual assignment looks more like:</p>
<p><span style="font-family: Courier">$my_arr[2] = $my_arr[0]</span><br style="font-family: Courier" /><span style="font-family: Courier">$my_arr[2] = $my_arr[1]</span><br style="font-family: Courier" /><span style="font-family: Courier">$my_arr[2] = $my_arr[2]</span><br style="font-family: Courier" /><br />
Thus we end up with $my_array being set as such on each iteration:</p>
<p><span style="font-family: Courier">// (array(1,2,1))  first element is set to value of last<br />
</span><span style="font-family: Courier">$my_arr[2] = $my_arr[0]<br />
</span><span style="font-family: Courier"><br />
// (array(1,2,2))  second element is set to value of last<br />
</span><span style="font-family: Courier">$my_arr[2] = $my_arr[1]<br />
</span><span style="font-family: Courier"><br />
// (array(1,2,2))  last element is set to value of itself</span><br style="font-family: Courier" /><span style="font-family: Courier">$my_arr[2] = $my_arr[2]<br />
</span><br />
Note that the last assignment is really assigning the last element to itself!</p>
<p>Because PHP5 handles variables with a copy on write algorithm, it’s typically not necessary to do any assignmnents by reference with performance gains in mind (as was the case with a lot of PHP4 code).  The above code can be made to function as the expected case by placing an unset($var) between the foreach loops, or not iterating over references and instead assigning the values of $my_arr explicitly by index or key values.  References should be used by care  and only when necessary.  When code like this is present in global scope or large functions it may affect future code in seemingly unpredictable ways.</p>
<p><!-- technorati tags begin --></p>
]]></content:encoded>
			<wfw:commentRss>http://ilovethat.info/blog/archives/49/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
