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

<channel>
	<title>绿色记忆 &#187; PHP</title>
	<atom:link href="https://blog.gmem.cc/category/work/web/php/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.gmem.cc</link>
	<description></description>
	<lastBuildDate>Mon, 06 Apr 2026 12:46:48 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.9.14</generator>
	<item>
		<title>PhpStorm知识集锦</title>
		<link>https://blog.gmem.cc/phpstorm-faq</link>
		<comments>https://blog.gmem.cc/phpstorm-faq#comments</comments>
		<pubDate>Thu, 12 May 2016 09:58:32 +0000</pubDate>
		<dc:creator><![CDATA[Alex]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[IntelliJ]]></category>
		<category><![CDATA[XDebug]]></category>

		<guid isPermaLink="false">https://blog.gmem.cc/?p=11503</guid>
		<description><![CDATA[<p>基础知识 简介 PHPStorm是一个基于IntelliJ平台跨平台的PHP集成开发环境，支持从5.3到最新的7.0的PHP版本。该IDE同时包含了WebStorm的功能，因此如果购买了PHPStorm，不需要再购买WebStorm。 部署 PhpStorm支持将工程部署到本地或者远程服务器，或者从远程服务器同步到本地。对于远程服务器，需要进行FTP或者SFTP的配置。 部署到本地服务器 File ⇨ Settings，定位到B,E,D ⇨ Deployment，点击右侧面板的+号，出现类似下面的界面： 勾选Visible only for this project则其它工程无法看到此部署配置，Folder填写本地HTTP服务器的部署根目录。 切换到Mappings选项卡，可以配置工程中目录与服务器目录的映射关系： 在选项卡Excluded Paths中，可以排除掉不需要在工程、服务器之间同步的文件。 执行部署操作 在Project窗口中，右击某个节点，或者在编辑器上右击，均可执行Upload to Server name操作，完成部署。 <a class="read-more" href="https://blog.gmem.cc/phpstorm-faq">[...]</a></p>
<p>The post <a rel="nofollow" href="https://blog.gmem.cc/phpstorm-faq">PhpStorm知识集锦</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></description>
				<content:encoded><![CDATA[<div class="wri_content_clear_both"><div class="blog_h1"><span class="graybg">基础知识</span></div>
<div class="blog_h2"><span class="graybg">简介</span></div>
<p>PHPStorm是一个基于IntelliJ平台跨平台的PHP集成开发环境，支持从5.3到最新的7.0的PHP版本。该IDE同时包含了WebStorm的功能，因此如果购买了PHPStorm，不需要再购买WebStorm。</p>
<div class="blog_h2"><span class="graybg">部署</span></div>
<p>PhpStorm支持将工程<span style="background-color: #c0c0c0;">部署</span>到本地或者远程服务器，或者从远程服务器<span style="background-color: #c0c0c0;">同步</span>到本地。对于远程服务器，需要进行FTP或者SFTP的配置。</p>
<div class="blog_h3"><span class="graybg">部署到本地服务器</span></div>
<p>File ⇨ Settings，定位到B,E,D ⇨ Deployment，点击右侧面板的+号，出现类似下面的界面：</p>
<p><img class="aligncenter size-full wp-image-11525" src="https://blog.gmem.cc/wp-content/uploads/2016/05/Selection_006.png" alt="Selection_006" width="100%" /></p>
<p>勾选Visible only for this project则其它工程无法看到此部署配置，Folder填写本地HTTP服务器的部署根目录。</p>
<p>切换到Mappings选项卡，可以配置工程中目录与服务器目录的映射关系：</p>
<p><img class="aligncenter size-full wp-image-11526" src="https://blog.gmem.cc/wp-content/uploads/2016/05/Selection_007.png" alt="Selection_007" width="100%" /></p>
<p>在选项卡Excluded Paths中，可以排除掉不需要在工程、服务器之间同步的文件。</p>
<div class="blog_h3"><span class="graybg">执行部署操作</span></div>
<p>在Project窗口中，右击某个节点，或者在编辑器上右击，均可执行Upload to Server name操作，完成部署。</p>
<p>注意在Debug时，必须先把工程中修改的文件部署到服务器上。</p>
<div class="blog_h2"><span class="graybg">调试</span></div>
<p>File ⇨ Settings，定位到Languages &amp; Frameworks ⇨ PHP ⇨ Debug，参考下图设置：</p>
<p><img class="aligncenter size-full wp-image-11512" src="https://blog.gmem.cc/wp-content/uploads/2016/05/Selection_004.png" alt="Selection_004" width="100%" /></p>
<p>Run ⇨ Break at first line in PHP scripts，取消勾选，否则每个PHP文件的<span style="background-color: #c0c0c0;">第一行都会中断执行</span>，很烦人。</p>
<div class="blog_h3"><span class="graybg">PHP服务器设置</span></div>
<p>File ⇨ Settings，定位到Languages &amp; Frameworks ⇨ PHP ⇨ Servers，在此对被调试的Web服务器进行配置。</p>
<p>注意<span style="background-color: #c0c0c0;">工程目录与服务器绝对路径之间的映射关系</span>要设置正确，PHP脚本在服务器上的绝对路径会在Debug会话中传递到PhpStorm，PhpStorm依据前述的映射关系确定源码位置。你必须保证工程文件和服务器文件内容一致。</p>
<p>参考下图进行设置：</p>
<p><img class="aligncenter size-full wp-image-11516" src="https://blog.gmem.cc/wp-content/uploads/2016/05/Selection_0021.png" alt="Selection_002" width="100%" /></p>
<div class="blog_h3"><span class="graybg">Run/Debug配置</span></div>
<p>你还需要配置调试的入口点。点击工具栏<img class="aligncenter size-full wp-image-11521 inlineBlock" src="https://blog.gmem.cc/wp-content/uploads/2016/05/Selection_0041.png" alt="Selection_004" width="46" height="17" /> 左侧的下拉按钮，选择Edit Configurations，点击+号，选择PHP Web Application，参考下图进行设置：</p>
<p><img class="aligncenter size-large wp-image-11522" src="https://blog.gmem.cc/wp-content/uploads/2016/05/Selection_005-1024x411.png" alt="Selection_005" width="100%" /></p>
<p>注意，如果你的服务器使用HTTPS协议，则Start URL必须填写完整的URL。</p>
<div class="blog_h3"><span class="graybg">执行调试</span></div>
<p>选中刚刚完成的Debug配置，按Alt + Shift + D或者点击工具栏上的甲虫图标即可启动调试，顺利的话，程序将在你设置好的断点处暂停。</p>
<div class="blog_h1"><span class="graybg">常见问题</span></div>
<div class="blog_h2"><span class="graybg">零散问题</span></div>
<div class="blog_h3"><span class="graybg">如何移除编辑器中的水平横线</span></div>
<p>默认情况下PHPStorm的编辑器，在类、方法前面显示一条水平横线作为分隔符，要去除，可以按如下步骤：</p>
<p>Preferences ⇨  Editor  ⇨ Colors &amp; Fonts  ⇨ General ⇨ Code ⇨ Method separator color，取消颜色设置。</p>
</div><p>The post <a rel="nofollow" href="https://blog.gmem.cc/phpstorm-faq">PhpStorm知识集锦</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.gmem.cc/phpstorm-faq/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP知识集锦</title>
		<link>https://blog.gmem.cc/php-faq</link>
		<comments>https://blog.gmem.cc/php-faq#comments</comments>
		<pubDate>Wed, 11 Dec 2013 08:56:07 +0000</pubDate>
		<dc:creator><![CDATA[Alex]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[FAQ]]></category>

		<guid isPermaLink="false">http://blog.gmem.cc/?p=863</guid>
		<description><![CDATA[<p>性能优化 非代码级优化 通用内核参数调优 参考Linux知识集锦。 调整连接数 [crayon-69d3f17e353fb064789116/] 相应的调整内核参数：[crayon-69d3f17e35402080764553-i/]  启用Zend Opcache [crayon-69d3f17e35404394050554/] 启用HugePage Linux的HugePage可以让PHP的TEXT段、内存分页都以巨页的方式存储，减少TLB相关的性能损耗。 先设置内核参数：[crayon-69d3f17e35407744023933-i/] 然后配置：[crayon-69d3f17e35409806923886-i/] 使用新版编译器 GCC 4.8以上编译器能够提升5%的性能，原因是开启Global Register对opline/execute_data的支持。 使用PGO编译 所谓剖析引导优化（PGO，Profile Guided Optimization），是通过剖析，给编译器以目标应用程序特点的提示信息，然后编译器进行针对性优化的技术。 <a class="read-more" href="https://blog.gmem.cc/php-faq">[...]</a></p>
<p>The post <a rel="nofollow" href="https://blog.gmem.cc/php-faq">PHP知识集锦</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></description>
				<content:encoded><![CDATA[<div class="wri_content_clear_both"><div class="blog_h1"><span class="graybg">性能优化</span></div>
<div class="blog_h2"><span class="graybg">非代码级优化</span></div>
<div class="blog_h3"><span class="graybg">通用内核参数调优</span></div>
<p>参考<a href="/linux-faq#kernel-params-opt-ref">Linux知识集锦</a>。</p>
<div class="blog_h3"><span class="graybg">调整连接数</span></div>
<pre class="crayon-plain-tag">; 根据QPS调整
listen.backlog = 65536</pre>
<p>相应的调整内核参数：<pre class="crayon-plain-tag">sysctl net.core.somaxconn=65536</pre> </p>
<div class="blog_h3"><span class="graybg">启用Zend Opcache</span></div>
<pre class="crayon-plain-tag">zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=512
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.max_wasted_percentage=5
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.revalidate_path=0
opcache.huge_code_pages=1</pre>
<div class="blog_h3"><span class="graybg">启用HugePage</span></div>
<p>Linux的HugePage可以让PHP的TEXT段、内存分页都以巨页的方式存储，减少TLB相关的性能损耗。</p>
<p>先设置内核参数：<pre class="crayon-plain-tag">sysctl vm.nr_hugepages=128</pre></p>
<p>然后配置：<pre class="crayon-plain-tag">opcache.huge_code_pages=1</pre></p>
<div class="blog_h3"><span class="graybg">使用新版编译器</span></div>
<p>GCC 4.8以上编译器能够提升5%的性能，原因是开启Global Register对opline/execute_data的支持。</p>
<div class="blog_h3"><span class="graybg">使用PGO编译</span></div>
<p>所谓剖析引导优化（PGO，Profile Guided Optimization），是通过剖析，给编译器以目标应用程序特点的提示信息，然后编译器进行针对性优化的技术。</p>
<p>首先，构建能产生Profile的二进制文件：</p>
<pre class="crayon-plain-tag">make prof-gen -j 8</pre>
<p>然后，开始运行PHP-FPM，进行训练：</p>
<pre class="crayon-plain-tag">/php-7.3.1/sapi/fpm/php-fpm -R --fpm-config /usr/local/php/etc/php-fpm.conf</pre>
<p>最后，重新编译并安装：</p>
<pre class="crayon-plain-tag">make prof-clean 
make prof-use -j 8 &amp;&amp; make install</pre>
<div class="blog_h1"><span class="graybg">OPcache</span></div>
<p>OPcache通过将 PHP 脚本<span style="background-color: #c0c0c0;">预编译的字节码存储到共享内存</span>中来提升 PHP 的性能， 存储预编译字节码的好处就是<span style="background-color: #c0c0c0;">省去了每次加载和解析 PHP 脚本的开销</span>。PHP 5.5.0 及后续版本中已经绑定了 OPcache 扩展。</p>
<p>如果OPcache和Xdebug一起使用，必须先加载OPcache。</p>
<div class="blog_h2"><span class="graybg">安装</span></div>
<p>OPcache只能编译为共享扩展。如果你通过--disable-all禁用了默认扩展的构建，则需要--enable-opcache来开启OPcache。</p>
<p>编译之后，可以用下面的指令将该扩展加载到PHP中：</p>
<pre class="crayon-plain-tag">zend_extension=/full/path/to/opcache.so</pre>
<div class="blog_h2"><span class="graybg">配置</span></div>
<table class="full-width fixed-word-wrap">
<thead>
<tr>
<td style="width: 250px; text-align: center;">配置项</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>opcache.enable</td>
<td>
<p>默认1，可修改范围PHP_INI_ALL</p>
<p>启用操作码缓存。如果禁用此选项，则不会优化和缓存代码。在运行期使用 ini_set() 函数只能禁用 opcache.enable 设置，不可以启用</p>
</td>
</tr>
<tr>
<td>opcache.enable_cli</td>
<td>
<p>默认0，PHP_INI_SYSTEM</p>
<p>仅针对 CLI 版本的 PHP 启用操作码缓存</p>
</td>
</tr>
<tr>
<td>opcache.memory_consumption</td>
<td>
<p>默认64，PHP_INI_SYSTEM</p>
<p>OPcache 的共享内存大小，单位MB</p>
</td>
</tr>
<tr>
<td>opcache.interned_strings_buffer</td>
<td>
<p>默认4，PHP_INI_SYSTEM</p>
<p>用来存储预留字符串的内存大小，单位MB</p>
</td>
</tr>
<tr>
<td>opcache.max_accelerated_files</td>
<td>
<p>默认2000，PHP_INI_SYSTEM</p>
<p>OPcache 哈希表中可存储的脚本文件数量上限，200-1000000之间</p>
<p>真实的取值是在质数集合 { 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987 } 中找到的第一个大于等于设置值的质数</p>
</td>
</tr>
<tr>
<td>opcache.max_wasted_percentage</td>
<td>
<p>默认5，PHP_INI_SYSTEM</p>
<p>浪费内存的上限，以百分比计。 如果达到此上限</p>
</td>
</tr>
<tr>
<td>opcache.use_cwd</td>
<td>
<p>默认1，PHP_INI_SYSTEM</p>
<p>哈希表的键是脚本的名字+脚本的工作目录，这样可以避免同名脚本导致键冲突</p>
<p>禁用此选项可以提高性能，但是可能会导致应用崩溃</p>
</td>
</tr>
<tr>
<td>opcache.validate_timestamps</td>
<td>
<p>默认1，PHP_INI_ALL</p>
<p>如果启用，那么 OPcache 会每隔 opcache.revalidate_freq秒检查脚本是否更新</p>
<p>如果禁用，则需要使用 opcache_reset() 或者 opcache_invalidate() 函数来手动重置 OPcache，或者重启Web服务</p>
</td>
</tr>
<tr>
<td>opcache.revalidate_freq</td>
<td>
<p>默认2，PHP_INI_ALL</p>
<p>检查脚本时间戳是否有更新的周期，以秒为单位</p>
</td>
</tr>
<tr>
<td>opcache.save_comments</td>
<td>
<p>默认1，PHP_INI_SYSTEM</p>
<p>如果禁用，脚本文件中的注释内容将不会被包含到操作码缓存文件， 这样可以有效减小优化后的文件体积。 禁用此配置指令可能会导致一些依赖注释或注解的 应用或框架无法正常工作， 比如： Doctrine， Zend Framework 2 以及 PHPUnit</p>
</td>
</tr>
<tr>
<td>opcache.enable_file_override</td>
<td>
<p>默认0，PHP_INI_SYSTEM</p>
<p>如果启用，则在调用函数 file_exists()， is_file() 以及 is_readable() 的时候， 都会检查操作码缓存，无论文件是否已经被缓存。 如果应用中包含检查 PHP 脚本存在性和可读性的功能，这样可以提升性能</p>
</td>
</tr>
<tr>
<td>opcache.optimization_level</td>
<td>
<p>默认0x7FFFBFFF，PHP_INI_SYSTEM</p>
<p>控制优化级别的二进制位掩码</p>
</td>
</tr>
<tr>
<td>opcache.blacklist_filename</td>
<td>
<p>默认""，PHP_INI_SYSTEM</p>
<p>OPcache 黑名单文件位置。 黑名单文件为文本文件，包含了不进行预编译优化的文件名，每行一个文件名。 黑名单中的文件名可以使用通配符，也可以使用前缀。 此文件中以分号开头的行将被视为注释</p>
</td>
</tr>
<tr>
<td>opcache.max_file_size</td>
<td>
<p>默认0，PHP_INI_SYSTEM</p>
<p>以字节为单位的缓存的文件大小上限。设置为 0 表示缓存全部文件</p>
</td>
</tr>
<tr>
<td>opcache.consistency_checks</td>
<td>
<p>默认0，PHP_INI_ALL</p>
<p>如果是非 0 值，OPcache 将会每隔 N 次请求检查缓存校验和。 N 即为此配置指令的设置值</p>
</td>
</tr>
<tr>
<td>opcache.force_restart_timeout</td>
<td>
<p>默认180，PHP_INI_SYSTEM</p>
<p>如果缓存处于非激活状态，等待多少秒之后计划重启。 如果超出了设定时间，则 OPcache 模块将杀除持有缓存锁的进程， 并进行重启</p>
</td>
</tr>
<tr>
<td>opcache.error_log</td>
<td>
<p>默认""，PHP_INI_SYSTEM</p>
<p>OPcache 模块的错误日志文件。 如果留空，则视为 stderr， 错误日志将被送往标准错误输出</p>
</td>
</tr>
<tr>
<td>opcache.log_verbosity_level</td>
<td>
<p>默认1，PHP_INI_SYSTEM</p>
<p>OPcache 模块的日志级别。 默认情况下，仅有致命级别（0）及错误级别（1）的日志会被记录。 其他可用的级别有：警告（2），信息（3）和调试（4）</p>
</td>
</tr>
<tr>
<td>opcache.preferred_memory_model</td>
<td>
<p>默认""，PHP_INI_SYSTEM</p>
<p>通常情况下，自动选择就可以满足需求。可选值包括： mmap，shm, posix 以及 win32</p>
</td>
</tr>
<tr>
<td>opcache.restrict_api</td>
<td>
<p>默认""，PHP_INI_SYSTEM</p>
<p>仅允许路径是以指定字符串开始的 PHP 脚本调用 OPcache API 函数。 默认值为空字符串 ""，表示不做限制</p>
</td>
</tr>
<tr>
<td>opcache.file_update_protection</td>
<td>
<p>默认2，PHP_INI_ALL</p>
<p>如果文件的最后修改时间距现在不足此项配置指令所设定的秒数，那么这个文件不会进入到缓存中。 这是为了防止尚未完全修改完毕的文件进入到缓存。 如果你的应用中不存在部分修改文件的情况，把此项设置为 0 可以提高性能</p>
</td>
</tr>
<tr>
<td>opcache.huge_code_pages</td>
<td>
<p>默认0，PHP_INI_SYSTEM</p>
<p>启用或者禁用将 PHP 代码（文本段）拷贝到 HUGE PAGES 中。 此项配置指令可以提高性能，但是需要在 OS 层面进行对应的配置</p>
</td>
</tr>
<tr>
<td>opcache.lockfile_path</td>
<td>
<p>默认/tmp，PHP_INI_SYSTEM</p>
<p>用来存储共享锁文件的绝对路径</p>
</td>
</tr>
<tr>
<td>opcache.file_cache</td>
<td>
<p>默认NULL，PHP_INI_SYSTEM</p>
<p>置二级缓存目录并启用二级缓存。 启用二级缓存可以在 SHM 内存满了、服务器重启或者重置 SHM 的时候提高性能。 默认值为空字符串 ""，表示禁用基于文件的缓存</p>
</td>
</tr>
<tr>
<td>opcache.file_cache_only</td>
<td>
<p>默认0，PHP_INI_SYSTEM</p>
<p>启用或禁用在共享内存中的 opcode 缓存</p>
</td>
</tr>
<tr>
<td>opcache.file_cache_consistency_checks</td>
<td>
<p>默认1，PHP_INI_SYSTEM</p>
<p>当从文件缓存中加载脚本的时候，是否对文件的校验和进行验证</p>
</td>
</tr>
</tbody>
</table>
<div class="blog_h3"><span class="graybg">推荐配置</span></div>
<p>官方文档的推荐配置如下：</p>
<pre class="crayon-plain-tag">opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1</pre>
<div class="blog_h1"><span class="graybg">编程知识</span></div>
<div class="blog_h2"><span class="graybg">常用代码片段</span></div>
<div class="blog_h3"><span class="graybg">解析JSON</span></div>
<p>可以使用json_decode函数：</p>
<pre class="crayon-plain-tag">/**
 * @param $json 带解析的JSON字符串
 * @param $assoc 如果设置为true，返回结果被转换为关联数组
 * @param $depth 最大递归深度
 * @param $options 选项位域，目前仅支持JSON_BIGINT_AS_STRING 
 * @return 与JSON内容对应的PHP类型，如果无法解析返回null
 */
mixed json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] );</pre>
<div class="blog_h3"><span class="graybg">正则式匹配</span></div>
<p>使用函数：</p>
<pre class="crayon-plain-tag">/**
 * 搜索一个匹配正则式的子串
 *
 * @param $pattern 用于匹配的正则式，注意 / / 包围
 * @param $subject 被匹配的字符串
 * @param &amp;$matches 可选，存放匹配结果的数组引用。第一个元素将存放完整匹配的子串，之后的元素对应每个捕获（用括号包围的子正则式）的匹配
 * @param $flags 匹配标记，可选值：
 *               PREG_OFFSET_CAPTURE  把匹配的子串位于字符串的偏移量添加到$matches数组
 * @param $offset 开始搜索的偏移量，单位字节
 * @return 如果不匹配，返回0，否则返回1
 */
int preg_match ( string $pattern , string $subject [, array &amp;$matches [, int $flags = 0 [, int $offset = 0 ]]] );
/**
 * 搜索全部匹配
 */
int preg_match_all ( string $pattern , string $subject 
                     [, array &amp;$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]] )</pre>
<p>示例：</p>
<pre class="crayon-plain-tag">preg_match('/crayon-[0-9a-f]+-i/',$capture[2]);</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
</div><p>The post <a rel="nofollow" href="https://blog.gmem.cc/php-faq">PHP知识集锦</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.gmem.cc/php-faq/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows下使用Eclipse PDT + XAMPP + XDebug调试PHP</title>
		<link>https://blog.gmem.cc/debug-php-with-eclipse-pdt-and-xdebug</link>
		<comments>https://blog.gmem.cc/debug-php-with-eclipse-pdt-and-xdebug#comments</comments>
		<pubDate>Fri, 08 Mar 2013 10:20:03 +0000</pubDate>
		<dc:creator><![CDATA[Alex]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[PDT]]></category>
		<category><![CDATA[XDebug]]></category>

		<guid isPermaLink="false">http://blog.gmem.cc/?p=686</guid>
		<description><![CDATA[<p>环境说明：Windows 7 X64，Eclipse 4.3.2，XAMPP 1.8.3 XDebug的设置 定位到%XAMPP_HOME%\php\php.ini，打开编辑 [crayon-69d3f17e359b3038886347/] Eclipse配置 Windows- Preferences - PHP - PHP Servers，添加服务器，注意Base URL和xdebug的域名保持对应： 最好避免使用Path Mapping————保持URI路径和Eclipse工程名称对应，我的环境下（Eclipse 4.3.2）出现无法识别断点的问题，没查出原因。 Windows- Preferences <a class="read-more" href="https://blog.gmem.cc/debug-php-with-eclipse-pdt-and-xdebug">[...]</a></p>
<p>The post <a rel="nofollow" href="https://blog.gmem.cc/debug-php-with-eclipse-pdt-and-xdebug">Windows下使用Eclipse PDT + XAMPP + XDebug调试PHP</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></description>
				<content:encoded><![CDATA[<div class="wri_content_clear_both"><p>环境说明：Windows 7 X64，Eclipse 4.3.2，XAMPP 1.8.3</p>
<p><strong>XDebug的设置</strong><br /> 定位到%XAMPP_HOME%\php\php.ini，打开编辑</p>
<pre class="crayon-plain-tag">[XDebug]
zend_extension = "D:\JavaEE\container\xampp\1.8.3\php\ext\php_xdebug.dll"
xdebug.profiler_append = 0
xdebug.profiler_enable = 1
xdebug.profiler_enable_trigger = 0
xdebug.profiler_output_dir = "D:\JavaEE\container\xampp\1.8.3\tmp"
xdebug.profiler_output_name = "cachegrind.out.%t-%s"
;启用远程调试
xdebug.remote_enable = 1
;调试客户端IP地址或者主机名
xdebug.remote_host = "gmem.cc"
;端口和Eclipse PDT保持一致
xdebug.remote_port = 9000
xdebug.remote_handler = "dbgp"
xdebug.trace_output_dir = "D:\JavaEE\container\xampp\1.8.3\tmp"</pre>
<p><strong>Eclipse配置</strong><br /> Windows- Preferences - PHP - PHP Servers，添加服务器，注意Base URL和xdebug的域名保持对应：<br /> <img src="https://blog.gmem.cc/wp-content/uploads/2013/03/eclipse-php-server-cfg.jpg" alt="eclipse-php-server-cfg" /><br /> 最好避免使用Path Mapping————保持URI路径和Eclipse工程名称对应，我的环境下（Eclipse 4.3.2）出现无法识别断点的问题，没查出原因。</p>
<p>Windows- Preferences - PHP - Debug，参考下图进行设置：<br /> <img src="https://blog.gmem.cc/wp-content/uploads/2013/03/eclipse-php-debug-cfg.jpg" alt="eclipse-php-debug-cfg" /></p>
<p>Windows- Preferences - PHP - Debug - Workbench Options，参考下图进行设置：<br /> PHP Debug View可以实时看到PHP输出的HTML内容<br /> <img src="https://blog.gmem.cc/wp-content/uploads/2013/03/eclipse-php-debug-cfg2.jpg" alt="eclipse-php-debug-cfg2" /></p>
<p><strong>Apache配置</strong><br /> 定位到%XAMPP_HOME%\apache\conf\httpd.conf，添加：</p>
<pre class="crayon-plain-tag">&lt;IfModule dir_module&gt;
    DirectoryIndex index.html index.php index.htm
    Alias /blog "D:/JavaEE/projects/eclipse/4.3.2/gmem-blog"
    &lt;Directory D:/JavaEE/projects/eclipse/4.3.2/gmem-blog&gt;
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
    &lt;/Directory&gt;
&lt;/IfModule&gt;</pre>
<p>注意Alias是PHP工程的部署URI，Eclipse工程的名称最好和它对应，避免麻烦。</p>
<p><strong>调试测试</strong><br /> 写几个PHP，使用include进行页面包含，然后设置一些端点，在PHP上点击右键，Debug As - PHP Web Application，确认程序在断点处暂停，Debug Output View输出对应的HTML内容。</p>
</div><p>The post <a rel="nofollow" href="https://blog.gmem.cc/debug-php-with-eclipse-pdt-and-xdebug">Windows下使用Eclipse PDT + XAMPP + XDebug调试PHP</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.gmem.cc/debug-php-with-eclipse-pdt-and-xdebug/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux下WordPress的相关问题</title>
		<link>https://blog.gmem.cc/wordpress-faq</link>
		<comments>https://blog.gmem.cc/wordpress-faq#comments</comments>
		<pubDate>Fri, 16 Mar 2012 14:29:22 +0000</pubDate>
		<dc:creator><![CDATA[Alex]]></dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://blog.gmem.cc/?p=1192</guid>
		<description><![CDATA[<p>修改为Restful风格URL后，出现404错误的问题 htaccess要开放写权限，这样在自定义wp的永久链接时，wp会自动重写.htaccess。最方便的是把整个Wordpress目录的所有权转移给www-data： [crayon-69d3f17e35bc8723298870/] Apache要开启Rewrite模块： a2enmod rewrite 查看Apache文件中的httpd.conf文件是否默认设置了AllowOverRide为None，如果是，要改成All。或者把Wordpress所在的vhost段的AllowOverRide改成All，示例： [crayon-69d3f17e35bcd465437956/]  如果仍然不行，看看Wordpress根目录是否存在.htaccess文件，如果不存在则手工创建： [crayon-69d3f17e35bcf036088973/] 如何更换域名 下面以：gmem.cc/blog替换为blog.gmem.cc的场景示例： 首先，在Wordpress管理界面中，更改Wordpress的URL设置 连接到数据库，执行以下语句： [crayon-69d3f17e35bd2082415320/] 打开IDE，执行全局替换 gmem.cc/blog替换为blog.gmem.cc</p>
<p>The post <a rel="nofollow" href="https://blog.gmem.cc/wordpress-faq">Linux下WordPress的相关问题</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></description>
				<content:encoded><![CDATA[<div class="wri_content_clear_both"><div class="blog_h3"><span class="graybg">修改为Restful风格URL后，出现404错误的问题</span></div>
<ol>
<li>htaccess要开放写权限，这样在自定义wp的永久链接时，wp会自动重写.htaccess。最方便的是把整个Wordpress目录的所有权转移给www-data：<br />
<pre class="crayon-plain-tag">chown www-data:www-data -R wordpress</pre>
</li>
<li>Apache要开启Rewrite模块： a2enmod rewrite</li>
<li>查看Apache文件中的httpd.conf文件是否默认设置了AllowOverRide为None，如果是，要改成All。或者把Wordpress所在的vhost段的AllowOverRide改成All，示例：<br />
<pre class="crayon-plain-tag">&lt;IfModule dir_module&gt;
    DirectoryIndex index.html index.php index.htm
    Alias /blog "D:/JavaEE/projects/eclipse/4.3.2/gmem-blog"
    &lt;Directory D:/JavaEE/projects/eclipse/4.3.2/gmem-blog&gt;
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
    &lt;/Directory&gt;
&lt;/IfModule&gt;</pre>
</li>
<li>
<p> 如果仍然不行，看看Wordpress根目录是否存在.htaccess文件，如果不存在则手工创建：</p>
<p><pre class="crayon-plain-tag"># BEGIN WordPress
&lt;IfModule mod_rewrite.c&gt;
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
&lt;/IfModule&gt;

# END WordPress</pre>
</li>
</ol>
<div class="blog_h3"><span class="graybg">如何更换域名</span></div>
<div>下面以：gmem.cc/blog替换为blog.gmem.cc的场景示例：
<ol>
<li>首先，在Wordpress管理界面中，更改Wordpress的URL设置</li>
<li>连接到数据库，执行以下语句：<br />
<pre class="crayon-plain-tag">UPDATE wp_posts SET post_content = replace( post_content, 'gmem.cc/blog','blog.gmem.cc') ;
UPDATE wp_comments SET comment_content = replace(comment_content, 'gmem.cc/blog', 'blog.gmem.cc') ;
UPDATE wp_comments SET comment_author_url = replace(comment_author_url, 'gmem.cc/blog', 'blog.gmem.cc') ;</pre>
</li>
<li>打开IDE，执行全局替换 gmem.cc/blog替换为blog.gmem.cc</li>
</ol>
</div>
</div><p>The post <a rel="nofollow" href="https://blog.gmem.cc/wordpress-faq">Linux下WordPress的相关问题</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.gmem.cc/wordpress-faq/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu下安装PHP</title>
		<link>https://blog.gmem.cc/php-under-ubuntu</link>
		<comments>https://blog.gmem.cc/php-under-ubuntu#comments</comments>
		<pubDate>Tue, 27 Dec 2011 13:00:10 +0000</pubDate>
		<dc:creator><![CDATA[Alex]]></dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XDebug]]></category>
		<category><![CDATA[容器化]]></category>

		<guid isPermaLink="false">http://blog.gmem.cc/?p=1184</guid>
		<description><![CDATA[<p>PHP5安装 安装必要的软件： [crayon-69d3f17e35e5e682946968/] 修改配置： 注意：Web服务器下编写info.php可以获知php.ini位置 [crayon-69d3f17e35e62685300627/] XDebug安装 安装必要的软件： [crayon-69d3f17e35e64845701006/] 修改配置文件：  [crayon-69d3f17e35e66690145151/] 重启Apache服务 [crayon-69d3f17e35e69840945491/] 现在调试客户端可以连接并进行调试了，需要注意的是，服务器必须能够连接到调试客户端。在调试位于外网服务器的PHP页面时，处于内网的调试客户端可能无法被直接访问，这时候最简单的方式就是使用VPN连接到服务器，上面的xdebug.remote_host填写VPN连接分配给客户端的IP地址即可。  调试完毕后，可以关闭xdebug模块： [crayon-69d3f17e35e6b511498045/] 验证XDebug正常工作 可以执行[crayon-69d3f17e35e6d567580247-i/]命令，如果输出： [crayon-69d3f17e35e6f624296730/]  说明XDebug正常加载。如果输出： [crayon-69d3f17e35e71763156355/] 说明PHP引擎和XDebug的版本不兼容。 <a class="read-more" href="https://blog.gmem.cc/php-under-ubuntu">[...]</a></p>
<p>The post <a rel="nofollow" href="https://blog.gmem.cc/php-under-ubuntu">Ubuntu下安装PHP</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></description>
				<content:encoded><![CDATA[<div class="wri_content_clear_both"><div class="blog_h2"><span class="graybg">PHP5安装</span></div>
<p>安装必要的软件：</p>
<pre class="crayon-plain-tag">sudo apt-get install php5-cgi</pre>
<p>修改配置：</p>
<p>注意：Web服务器下编写info.php可以获知php.ini位置</p>
<pre class="crayon-plain-tag">vim /etc/php5/apache2/php.ini 
#根据需要修改以下内容：
#最大上传文件的大小
upload_max_filesize = 20M 
#错误报告相关配置
error_reporting = E_ALL
display_errors = On
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
error_log = /var/log/php_errors.log
ignore_repeated_errors = Off
report_memleaks = On
track_errors = On</pre>
<div class="blog_h2"><span class="graybg">XDebug安装</span></div>
<p>安装必要的软件：</p>
<pre class="crayon-plain-tag"># 安装XDebug
apt-get install php5-xdebug

# 上述安装方法，有可能安装不匹配的XDebug版本，你可以使用PHP提供的扩展管理器PECL来安装，确保版本兼容：
# 要使用PECL，必须安装PHP的开发版本 sudo apt-get install php5-dev
# 安装PHP5最新稳定版本的XDebug
sudo pecl install php5-xdebug

# 启用PHP模块
php5enmod xdebug</pre>
<p>修改配置文件： </p>
<pre class="crayon-plain-tag">#下面这一行不要忘记
[XDebug]
xdebug.remote_autostart = 0

zend_extension="/usr/lib/php5/20121212/xdebug.so"
#禁用性能剖析
xdebug.profiler_enable = 0
#启用远程调试
xdebug.remote_enable = 1
#调试客户端IP地址或者主机名
xdebug.remote_host = 172.21.0.100
#调试客户端的监听端口
xdebug.remote_port = 9000
#是否启用回连，即由服务器主动连接调试客户端，服务器通过检查HTTP请求得知客户端的IP
#启用该选项时xdebug.remote_host无意义
xdebug.remote_connect_back = 0
xdebug.remote_handler = "dbgp"
xdebug.remote_mode = req
#所有的远程调试连接都会被记录到该日志
xdebug.remote_log = /var/log/xdebug.log</pre>
<div class="blog_h3"><span class="graybg">重启Apache服务</span></div>
<pre class="crayon-plain-tag">service apache2 restart</pre>
<p>现在调试客户端可以连接并进行调试了，需要注意的是，服务器必须能够连接到调试客户端。在调试位于外网服务器的PHP页面时，处于内网的调试客户端可能无法被直接访问，这时候最简单的方式就是使用VPN连接到服务器，上面的xdebug.remote_host填写VPN连接分配给客户端的IP地址即可。 </p>
<p>调试完毕后，可以关闭xdebug模块：</p>
<pre class="crayon-plain-tag">php5dismod xdebug

#在我的服务器上测试，即使禁用仍然对Apache2的性能产生影响，因此可以删除，需要的时候重新安装
apt-get remove php5-xdebug</pre>
<div class="blog_h3"><span class="graybg">验证XDebug正常工作</span></div>
<p>可以执行<pre class="crayon-plain-tag">php -v</pre>命令，如果输出：</p>
<pre class="crayon-plain-tag">PHP 5.6.30 (cli) (built: Feb 28 2017 17:33:47) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
    with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans</pre>
<p> 说明XDebug正常加载。如果输出：</p>
<pre class="crayon-plain-tag">Xdebug requires Zend Engine API version 220121212.
The Zend Engine API version 220131226 which is installed, is newer.
Contact Derick Rethans at http://xdebug.org/docs/faq#api for a later version of Xdebug.</pre>
<p>说明PHP引擎和XDebug的版本不兼容。</p>
<p>也可以通过phpinfo来验证，正常加载时，页面存在以下内容：</p>
<p><img class="aligncenter size-full wp-image-15104" src="https://blog.gmem.cc/wp-content/uploads/2011/12/phpinfo-xdebug.png" alt="phpinfo-xdebug" width="100%" /></p>
<div class="blog_h2"><span class="graybg">PHP7安装</span></div>
<pre class="crayon-plain-tag"># 独立构建并安装，避免影响系统既有PHP版本
tar xf php-7.0.6.tar.bz2
cd php-7.0.6
# 设置安装目录
./configure --prefix=/home/alex/PHP/7.0.6
make &amp;&amp; make install</pre>
<p>构建并安装XDebug：</p>
<pre class="crayon-plain-tag"># 安装XDebug
/home/alex/PHP/7.0.6/bin/php -i &gt; php7.txt
# 把输出拿到https://xdebug.org/wizard.php分析，该网站会显示如何构建XDebug
tar -xvzf xdebug-2.4.0.tgz
cd xdebug-2.4.0
/home/alex/PHP/7.0.6/bin/phpize
./configure --with-php-config=/home/alex/PHP/7.0.6/bin/php-config
make
cp modules/xdebug.so /home/alex/PHP/7.0.6/lib/php/extensions/no-debug-non-zts-20151012</pre>
<p>修改 /home/alex/PHP/7.0.6/lib/php.ini，添加：</p>
<pre class="crayon-plain-tag">[XDebug]
xdebug.remote_autostart = 0
zend_extension = /home/alex/PHP/7.0.6/lib/php/extensions/no-debug-non-zts-20151012/xdebug.so
xdebug.profiler_enable = 0
xdebug.remote_enable = 1
xdebug.remote_host = 127.0.0.1
xdebug.remote_port = 9000
xdebug.remote_connect_back = 0
xdebug.remote_handler = "dbgp"
xdebug.remote_mode = req
xdebug.remote_log = /home/alex/PHP/7.0.6/var/log/xdebug.log</pre>
<div class="blog_h2"><span class="graybg">容器化</span></div>
<div class="blog_h3"><span class="graybg">PHP5+Apache2</span></div>
<p>参考：<a href="/apache2-under-ubuntu#containerization">Ubuntu下安装Apache2服务器</a></p>
<div class="blog_h2"><span class="graybg">常见问题</span></div>
<div class="blog_h3"><span class="graybg">PHP Fatal error: Call to undefined function curl_init()</span></div>
<p>more /var/log/apache2/error.log，发现错误该错误，原因：未安装CURL支持，解决方式：</p>
<pre class="crayon-plain-tag">apt-get install php5-curl
service apache2 restart</pre>
<p>&nbsp;</p>
</div><p>The post <a rel="nofollow" href="https://blog.gmem.cc/php-under-ubuntu">Ubuntu下安装PHP</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.gmem.cc/php-under-ubuntu/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP5学习笔记</title>
		<link>https://blog.gmem.cc/php5-study-note</link>
		<comments>https://blog.gmem.cc/php5-study-note#comments</comments>
		<pubDate>Thu, 15 May 2008 04:11:46 +0000</pubDate>
		<dc:creator><![CDATA[Alex]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.gmem.cc/?p=872</guid>
		<description><![CDATA[<p>第一部分：语言基础 PHP5注释 C方式：[crayon-69d3f17e3658d466628769-i/] 这是一个C风格的注释 *它可以跨越多行 *直到关闭标记 C++方式：[crayon-69d3f17e36591877140295-i/] 这是一个C++风格的注释，它在行的末尾结束 Shell方式：[crayon-69d3f17e36593464363722-i/] 这是一个Shell风格的注释，它在行的末尾结束 PHP5变量 变量不需要声明直接使用，可以自动改变类型，用[crayon-69d3f17e36595108427639-i/] 标志当变量名的前缀 主脚本中定义的变量，若在函数中使用，需要[crayon-69d3f17e36597408696886-i/] 方式引用 不支持全局变量，除了预定义的超全局变量： 超全局变量 说明 [crayon-69d3f17e36599057078671-i/]  包含所有PHP从客户浏览器接收的GET参数的数组，包括通过URL发送的数据 [crayon-69d3f17e3659b063603359-i/]  包含所有PHP从客户浏览器接收的POST参数的数组 [crayon-69d3f17e3659d516949504-i/]  包含所有请求参数的数组 [crayon-69d3f17e3659f289944504-i/]  包含所有PHP从客户浏览器接收的cookies的数组 [crayon-69d3f17e365a2399122080-i/]  <a class="read-more" href="https://blog.gmem.cc/php5-study-note">[...]</a></p>
<p>The post <a rel="nofollow" href="https://blog.gmem.cc/php5-study-note">PHP5学习笔记</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></description>
				<content:encoded><![CDATA[<div class="wri_content_clear_both"><div class="blog_h1"><span class="graybg">第一部分：语言基础</span></div>
<div class="blog_h2"><span class="graybg">PHP5注释</span></div>
<p>C方式：<pre class="crayon-plain-tag">/**/</pre> 这是一个C风格的注释 *它可以跨越多行 *直到关闭标记<br /> C++方式：<pre class="crayon-plain-tag">//</pre> 这是一个C++风格的注释，它在行的末尾结束<br /> Shell方式：<pre class="crayon-plain-tag">#</pre> 这是一个Shell风格的注释，它在行的末尾结束</p>
<div class="blog_h2"><span class="graybg">PHP5变量</span></div>
<div>
<ol>
<li>变量不需要声明直接使用，可以自动改变类型，用<pre class="crayon-plain-tag">$</pre> 标志当变量名的前缀</li>
<li>主脚本中定义的变量，若在函数中使用，需要<pre class="crayon-plain-tag">$GLOBALS[]</pre> 方式引用</li>
<li>不支持全局变量，除了预定义的超全局变量：</li>
</ol>
</div>
<div class="bstab">
<table class="full-width fixed-word-wrap">
<thead>
<tr>
<td style="width: 15%; text-align: center;">超全局变量</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td><pre class="crayon-plain-tag">$_GET[]</pre> </td>
<td>包含所有PHP从客户浏览器接收的GET参数的数组，包括通过URL发送的数据</td>
</tr>
<tr>
<td><pre class="crayon-plain-tag">$_POST[]</pre> </td>
<td>包含所有PHP从客户浏览器接收的POST参数的数组</td>
</tr>
<tr>
<td><pre class="crayon-plain-tag">_REQUEST</pre> </td>
<td>包含所有请求参数的数组</td>
</tr>
<tr>
<td><pre class="crayon-plain-tag">$_COOKIE[]</pre> </td>
<td>包含所有PHP从客户浏览器接收的cookies的数组</td>
</tr>
<tr>
<td><pre class="crayon-plain-tag">$_ENV[]</pre> </td>
<td>包含环境变量的数组</td>
</tr>
<tr>
<td><pre class="crayon-plain-tag">$_SERVER[]</pre> </td>
<td>存放服务器变量的数组<br />
<pre class="crayon-plain-tag">$_SERVER['PHP_SELF']	        #返回当前执行脚本的文件名。
$_SERVER['GATEWAY_INTERFACE']	#返回服务器使用的 CGI 规范的版本
$_SERVER['SERVER_ADDR']	        #返回当前运行脚本所在的服务器的IP地址
$_SERVER['SERVER_NAME']	        #返回当前运行脚本所在的服务器的主机名
$_SERVER['SERVER_SOFTWARE']	    #返回服务器标识字符串
$_SERVER['SERVER_PROTOCOL']	    #返回请求页面时通信协议的名称和版本，例如HTTP/1.0
$_SERVER['REQUEST_METHOD']	    #返回访问页面使用的请求方法
$_SERVER['REQUEST_TIME']	    #返回请求开始时的时间戳
$_SERVER['QUERY_STRING']	    #返回查询字符串，如果是通过查询字符串访问此页面。
$_SERVER['HTTP_ACCEPT']	        #返回来自当前请求的请求头
$_SERVER['HTTP_ACCEPT_CHARSET']	#返回来自当前请求的Accept_Charset头
$_SERVER['HTTP_HOST']	        #返回来自当前请求的Host头。
$_SERVER['HTTP_REFERER']	    #返回当前页面的完整URL
$_SERVER['HTTPS']	            #是否通过安全 HTTP 协议查询脚本
$_SERVER['REMOTE_ADDR']	        #返回浏览当前页面的用户的IP地址
$_SERVER['REMOTE_HOST']	        #返回浏览当前页面的用户的主机名。
$_SERVER['REMOTE_PORT']	        #返回用户机器上连接到Web服务器所使用的端口号
$_SERVER['SCRIPT_FILENAME']     #返回当前执行脚本的绝对路径
$_SERVER['SERVER_ADMIN']        #Apache服务器配置文件中的 ERVER_ADMIN参数
$_SERVER['SERVER_PORT']	        #Web服务器使用的端口
$_SERVER['SERVER_SIGNATURE']	#返回服务器版本和虚拟主机名
$_SERVER['PATH_TRANSLATED']     #当前脚本所在文件系统（非文档根目录）的基本路径
$_SERVER['SCRIPT_NAME']	        #返回当前脚本的路径
$_SERVER['SCRIPT_URI']	        #返回当前页面的 URI</pre>
</td>
</tr>
<tr>
<td><pre class="crayon-plain-tag">$_SESSION</pre> </td>
<td>存放会话变量的数组</td>
</tr>
</tbody>
</table>
</div>
<div class="blog_h3"><span class="graybg">变量类型提示</span></div>
<p>在PHP5中，允许在声明函数时，为<span style="background-color: #c0c0c0;">对象、接口、数组或者callable类型的入参</span>强制声明类型。对于字符串、整型等标量类型，不支持类型提示：</p>
<pre class="crayon-plain-tag">class Person {}
function sayHello (Person $p, $times) {}</pre>
<div class="blog_h3"><span class="graybg">变量的间接引用</span></div>
<div>
<pre class="crayon-plain-tag">$name = "John"；
$$name = "Registered user";   // $$$var 这样的形式也是可能的
print $John;                  // 打印：Registered user</pre>
</div>
<div class="blog_h3"><span class="graybg">变量管理函数</span></div>
<div>
<pre class="crayon-plain-tag">isset()                        // 用来判断某个变量是否已经被PHP声明。它返回一个布尔型的值
isset($arr["offset"])          // 如果$arr或者$obj["offset"]没有声明，则返回false
isset($obj-&gt;property)          // 如果$obj或者$obj-&gt;property没有声明，则返回false
isset{$varl, $var2, $var3);    // 如果所有变量均声明，则返回true
unset()                        // 可以取消定义之前定义的变量，如没有其他变量在引用它则释放内存
empty()                        // 可以用来检查一个变量是否没被声明或者值是false</pre>
</div>
<div class="blog_h2"><span class="graybg">基础数据类型</span></div>
<div>PHP包含8种数据类型，其中有5种属于数值类型。</div>
<div class="blog_h3"><span class="graybg">整型</span></div>
<div>值范围与C编译器的long值范围一致，支持8/10/16进制：<br />
<pre class="crayon-plain-tag">$x = 5985;
$x = - 345;
$x = 0x8C; // 十六进制数
$x = 047; // 八进制数</pre>
</div>
<div class="blog_h3"><span class="graybg">浮点型</span></div>
<p>值范围与C编译器double类型有关，可以使用科学计数法：</p>
<pre class="crayon-plain-tag">$x = 10.365;
$x = 2.4e3;
$x = 8E-5;</pre>
<div class="blog_h3"><span class="graybg">布尔型</span></div>
<p>表示逻辑的真假，可以取值<pre class="crayon-plain-tag">true</pre> 或者<pre class="crayon-plain-tag">false</pre> 。</p>
<div class="blog_h3"><span class="graybg">布尔转换规则</span></div>
<div>
<table class=" full-width fixed-word-wrap">
<thead>
<tr>
<td style="text-align: center;">数据类型</td>
<td style="text-align: center;">false值</td>
<td style="text-align: center;">true值</td>
</tr>
</thead>
<tbody>
<tr>
<td>整型</td>
<td>0</td>
<td>所有非零值</td>
</tr>
<tr>
<td>浮点型</td>
<td>0.0</td>
<td>所有非零值</td>
</tr>
<tr>
<td>字符串</td>
<td>""、"0"</td>
<td>所有其他字符串</td>
</tr>
<tr>
<td>NULL</td>
<td>总是</td>
<td>总不</td>
</tr>
<tr>
<td>数组</td>
<td>如果不含任何元素</td>
<td>含有一个以上元素</td>
</tr>
<tr>
<td>对象</td>
<td>总不</td>
<td>总是</td>
</tr>
<tr>
<td>资源</td>
<td>总不</td>
<td>总是</td>
</tr>
</tbody>
</table>
</div>
<div class="blog_h3"><span class="graybg">字符串</span></div>
<p>字符序列，自动地用null做结束的组合，与C字符串不一样的是，不需要以null符号计算其长度。字符串有三种表示方式：</p>
<pre class="crayon-plain-tag">#双引号界定的字符串：支持嵌入变量或者表达式，以及转义字符：
$str = "Hello,$user_name.\"";
$str = "The array offset $i contains $arr[$i]";

#单引号界定的字符串：不支持变量嵌入，仅支持'、\这两个字符的转义
$str = 'Hello, World';
$str = 'Today\'s the day';

#定界符界定的字符串：转义和嵌入变量的支持类似于""，但是不需要转义"
$str = &lt;&lt;&lt;DEMINITER
Hello
There
DEMINITER
#访问单个字符，索引从0开始
$c = $str{0};</pre>
<div class="blog_h3"><span class="graybg">数组</span></div>
<p>一个键/值对的集合，索引可以是整数或者字符串，值可以是任意类型：</p>
<pre class="crayon-plain-tag">// 声明关联数组
$arr = array(
    'key1' =&gt; 'val1',
    'key2' =&gt; 'val2',
    'key3' =&gt; 'val3'
);
// 声明索引数组，等价于 array(0 =&gt; 'a', 1 =&gt; 'b')
array(
    'a',
    'b'
);
// 声明索引数组，等价于 array(1 =&gt; "ONE", 2 =&gt; "TWO", 3 =&gt; "THREE" )
array(
    1 =&gt; "ONE",
    "TWO",
    "THREE"
);

// 访问数组元素
$arr[key];
// 获得数组长度
$c = count($arr);

// 通过数字索引遍历数组
$cars = array(
    "Volvo",
    "BMW"
);
$arrlength = count($cars);
for ($x = 0; $x &lt; $arrlength; $x ++) {
    echo $cars[$x];
}
// 通过foreach遍历数组: foreach($array as [$key =&gt; ] [&amp;] $value) {}
// 举例：
$user = array(
    "Bill" =&gt; "35",
    "Steve" =&gt; "37",
    "Peter" =&gt; "43"
);
foreach ($user as $name =&gt; $age) {
    echo "User " . $name . "'s age is " . $age;
}


$nums = [0, 1, 2];
$ass = array(
    'k0' =&gt; 0,
    'k1' =&gt; 1,
    'k2' =&gt; 2
);
# 可以把关联数组转换为索引数组
print_r(array_values($ass));

# 删除一个元素，但是不改变剩余元素的索引
unset($nums[1]);    # [ 0, 2 ]
unset($ass['k1']);  # { k0 =&gt; 0, k2 = &gt; 2 }


$nums = [1, 2, 3, 4, 5, 6];

# 切片操作，获得一个子数组
$sub = array_slice($nums, 1, 3); # [2, 3, 4]，源数组不变
# diff操作，根据值过滤，生成一个新数组，所有元素索引不变
$sub = array_diff($nums, [3, 4]);  # [1, 2, 4=&gt;5, 5=&gt;6]
# differ操作，根据key过滤，生成一个新数组，所有元素索引不变
# 注意第二个参数：key可以写为字符串，自动转换为索引数字；value则随意
$sub = array_diff_key($nums, [3 =&gt; null, '4' =&gt; null]); # [1, 2, 3, 5=&gt;6]


# 删除若干元素，并且reindex
array_splice($nums, 1, 3);  # 返回值也是 [2, 3, 4]，但是源数组也被修改：[1, 5, 6]</pre>
<p>索引为整数的数组，也称为<span style="background-color: #c0c0c0;">索引数组</span>；索引为字符串的数组，也称为<span style="background-color: #c0c0c0;">关联数组</span>。</p>
<div class="blog_h3"><span class="graybg">空值</span></div>
<p>这一特殊类型用于表示变量“没有值”，<pre class="crayon-plain-tag">null</pre> 是该类型唯一的有效值。</p>
<div class="blog_h3"><span class="graybg">常量</span></div>
<p>一经定义，全局可用，不能在新的函数、PHP文件中重新声明他们，声明语法：</p>
<pre class="crayon-plain-tag">define("CONSTANT_NAME", value [, case-sensitivity]);</pre>
<div class="blog_h2"><span class="graybg">PHP5运算符（按优先级高低降序排列）</span></div>
<div class="bstab">
<table class=" full-width fixed-word-wrap" style="width: 100%;">
<thead>
<tr>
<td style="width: 130px; text-align: center;">运算符</td>
<td style="width: 100px; text-align: center;">名称</td>
<td style="width: 80px; text-align: center;">结合性</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>new</td>
<td>创建对象</td>
<td>无</td>
<td>创建新的对象</td>
</tr>
<tr>
<td>[]</td>
<td>数组元素操控</td>
<td>右</td>
<td>读写数组的元素</td>
</tr>
<tr>
<td>!</td>
<td>逻辑否</td>
<td>右</td>
<td>后续表达式为true，则整个表达式为false</td>
</tr>
<tr>
<td>~</td>
<td>按位否</td>
<td>右</td>
<td>如果是数字操作数，得到的是操作数 按位非的结果（浮点值会被先转变为 整型值）如果是字符串，将得到相同长度并且每个字符都是原来字符接位非的新的字符串</td>
</tr>
<tr>
<td>++</td>
<td>递增</td>
<td>右</td>
<td>将变量的值增加1，包括$var++  ++$var两种</td>
</tr>
<tr>
<td>--</td>
<td>递减</td>
<td>右</td>
<td>将变量的值减小1 ，包括$var--   --$var两种</td>
</tr>
<tr>
<td>(type)</td>
<td>强制转型</td>
<td>右</td>
<td>包括： (int) (integer) (float) (real) (double)(string) (bool) (Boolean) (array) (object)</td>
</tr>
<tr>
<td>@</td>
<td>错误抑制</td>
<td>右</td>
<td>把表达式求值过程中的错误忽略掉</td>
</tr>
<tr>
<td>*    /    %    +    -</td>
<td>算术运算符</td>
<td>左</td>
<td>%为取模：两个操作数都被转变成整型，结果是第一个操作数 除第二个操作数余数</td>
</tr>
<tr>
<td>.</td>
<td>字符串连接</td>
<td>左</td>
<td>处理字符串的连接，非字符串会自动转换</td>
</tr>
<tr>
<td>&lt;&lt;</td>
<td>按位左移</td>
<td>左</td>
<td>按位左移，移出的丢弃，右侧补0</td>
</tr>
<tr>
<td>&gt;&gt;</td>
<td>按位右移</td>
<td>左</td>
<td>按位右移，移出的丢弃，左侧补0</td>
</tr>
<tr>
<td>&lt;   &lt;=</td>
<td>小于(等于)</td>
<td>无</td>
<td rowspan="4">逻辑运算，返回布尔值，字符串按字典序比较</td>
</tr>
<tr>
<td>&gt;   &gt;=</td>
<td>大于(等于)</td>
<td>无</td>
</tr>
<tr>
<td>==</td>
<td>等于</td>
<td>无</td>
</tr>
<tr>
<td>!=   &lt;&gt;</td>
<td>不等于</td>
<td>无</td>
</tr>
<tr>
<td>===</td>
<td>全等于</td>
<td>无</td>
<td rowspan="2">===与==相似，但是操作的数据类型必须匹配。不执行自动转换类型：例如1===”1″返回 false</td>
</tr>
<tr>
<td>!==</td>
<td>不全等于</td>
<td>无</td>
</tr>
<tr>
<td>&amp;</td>
<td>按位与</td>
<td>左</td>
<td>除非两个给定的参数都是字符串，否则参数将被转换到相应的整型数，然后再执行按位与运算</td>
</tr>
<tr>
<td>^</td>
<td>按位异或</td>
<td>左</td>
<td>除非两个给定的参数都是字符串，否则参数将被转换到相应的整型数，然后再执行按位异或运算</td>
</tr>
<tr>
<td>|</td>
<td>按位或</td>
<td>左</td>
<td>除非两个给定的参数都是字符串，否则参教将被转换到相应的整型数，然后再执行按位或运算</td>
</tr>
<tr>
<td>&amp;&amp;</td>
<td>逻辑与</td>
<td>左</td>
<td>短路，如果操作数1为false</td>
</tr>
<tr>
<td>||</td>
<td>逻辑或</td>
<td>左</td>
<td>短路，如果操作数1为true</td>
</tr>
<tr>
<td>?:</td>
<td>三目运算符</td>
<td>左</td>
<td> </td>
</tr>
<tr>
<td>=</td>
<td>赋值</td>
<td>左</td>
<td>将右操作数的值赋给左边的变量</td>
</tr>
<tr>
<td>=&amp;</td>
<td>引用赋值</td>
<td>左</td>
<td>相当于别名</td>
</tr>
<tr>
<td>+=   -=  *=  /=  .=%=  &amp;=  |=  ^=  ~=&lt;&lt;=  &gt;&gt;=</td>
<td>带操作的赋值</td>
<td>左</td>
<td>先执行指定的计算，在把计算结果赋给左值</td>
</tr>
<tr>
<td>and</td>
<td>逻辑与</td>
<td>左</td>
<td rowspan="3">类似上面的逻辑运算符，只是优先级更低</td>
</tr>
<tr>
<td>xor</td>
<td>逻辑异或</td>
<td>左</td>
</tr>
<tr>
<td>or</td>
<td>逻辑或</td>
<td>左</td>
</tr>
<tr>
<td>,</td>
<td>列表操作符</td>
<td>左</td>
<td> </td>
</tr>
</tbody>
</table>
</div>
<div class="blog_h2"><span class="graybg">PHP5程序控制结构</span></div>
<div class="blog_h3"><span class="graybg">条件控制结构</span></div>
<div>
<pre class="crayon-plain-tag">#C风格语法
if (expr)
    statement
elseif (expr)
    statement
elseif (expr)
    statement
else
    statement

#Pascal风格语法
if (expr)：
    statement list 
elseif (expr): 
    statement list 
else if (expr):
    statement list
else:
    statement list
endif;
#举例
<!--?php if ($num < 0): ?-->
    $num is negative<!--注意:HTML不会替换变量-->
<!--?php elseif{$num == 0): ?-->
    $num is zero
<!--?php elseif{$num --> 0): ?&gt;
    $num is positive
<!--?php endif; ?--></pre><br />
<pre class="crayon-plain-tag">#C风格语法
switch (expr){ 
    case expr:
        statement list 
    case expr:
        statement list
    default:
        statement list
}
#Pascal风格语法
switch (expr): 
    case expr:
        statement list
        break;#可以使用break跳出switch结构
    case expr:
        statement list
    default:
        statement list 
endswitch;
#举例
switch ($answer) { 
    case 'y': 
    case 'Y':
        print "The answer was yes\n";
        break;
    case 'n':
    case 'N':
        print "The answer was no\n";
        break;
    default: #如果没有匹配的，default语句被执行
        print "Error: $answer is not a valid answer\n";
        break;
}</pre>
</div>
<div class="blog_h3"><span class="graybg">循环控制结构</span></div>
<div>
<pre class="crayon-plain-tag">#C风格的while循环
while(expr)
    statement
#Pascal风格的while循环
while(expr):
    statementlist
endwhile;
#举例
$result = 1;
while ($n &gt; 0) {
    $result *= $n--;
    break;#用于跳出循环，break 1和break同义，表示跳出一层循环，类推，switch纳入计算
}
print "The result is $result";

#do-while循环
do{
    statement
}while(expr);

#C风格的for循环
for (expr, expr,…; expr,expr, …; expr,expr,…)
    statement
#Pascal风格的for循环
for (expr, expr,…; expr,expr, …; expr,expr,…):
    statementlist
endfor;</pre>
</div>
<div class="blog_h3"><span class="graybg">代码包含控制结构</span></div>
<div>include语句可以有返回值，被包含文件的作用域和主文件一致</div>
<div>
<pre class="crayon-plain-tag">#error_code.php
&lt;?php
    $OK = 0;
    $ERROR = 1;
?&gt;
#test.php
&lt;?php
    include "error_code.php";
    print("$OK");
    #include支持相对、绝对路径，动态合成绝对路径：
    include $_SERVER [ "DOCUMENT_ROOT"]."/script.php";
    #include遇到文件不存在的情况，会继续执行，要终止执行，可以使用require
    require "import.php";
?&gt;
#include_once、require_once保证只会包含进来一次</pre>
</div>
<div class="blog_h2"><span class="graybg">PHP5函数</span></div>
<p>函数作用域：默认情况下，<span style="background-color: #c0c0c0;">函数外部定义的变量，不能在函数内部访问</span>，使用<pre class="crayon-plain-tag">$GLOBALS[var_name]</pre> 可以提取并访问全局作用域的变量。<pre class="crayon-plain-tag">global</pre> 关键字可以引入全局变量到函数内部：</p>
<pre class="crayon-plain-tag">#函数声明语法
function function_name (argl, arg2, arg3,…){
    statement list
}
#声明函数时，函数名加&amp;前缀，则按引用方式传递返回值
function &amp;ret_by_ref ($n){
}
#声明函数时，参数名加&amp;前缀，则按引用方式传递参数
function &amp;arg_by_ref (&amp;$n,$default = 0){    #支持设置参数的默认值
    static times = 0;#支持静态函数变量
}
#函数调用语法
function_name (argl, arg2, arg3,…);

#global用法示例
global $varl, $var2,...;
function func{)
    global $var;
    $var = 2;
}
$var = 1;func();
print $var;#打印2</pre>
<div class="blog_h1"><span class="graybg">第二部分：面向对象特性</span></div>
<div class="blog_h2"><span class="graybg">类的声明和使用</span></div>
<div>
<pre class="crayon-plain-tag">class Person {
    function __construct($name)
    {
        $this-&gt;name = $name;
    }
    function getName()
    {
        #方法执行时，PHP自动生成$this变量
        return $this-&gt;name;
    }
    private $name;
    public $dob;
}；
$alex = new Person('Alex');
print $alex -&gt; getName();#使用-&gt;操作符访问对象成员
print $alex -&gt; dob;#注意，访问属性不要加$前缀 

#public/private/protected访问修饰符，针对对象中的方法和属性：
#PHP4的var声明还是支持的
class MyClass {
    private $id = 18;
    public function getld() { return $this-&gt;id;}
}
#统一构造函数名__construct ()：
class MyClass {
    function  __construct{) {
        print "Inside constructor";
    }
}
#统一析构函数名：__destruct()：
class MyClass {
    function __destruct()    {
        print "Destroying object";
    }
}
#instanceof 操作符PHP4的is_a()函数不推荐使用：
if ($obj instanceof Circle) { print '$obj is a Circle';}
#final标记方法 Final关键字允许你用来标识方法，使其不能被子类重载： 
class MyClass {
    final function getBaseClassName(){};
}
#final标记类,声明一个类为final类型后，它将不能被继承
final class FinalClass {}
class BogusClass extends FinalClass {}//错误

#强制复制对象，为了克隆一个对象，必须使用clone关键字
class MyClass {
function  __clone() {
    print "Object is being cloned";
}
$obj = new MyClass();
$obj_copy = clone $obj;

#类定义中现在包含常量，而且可以用类来引用:
class MyClass {
    const SUCCESS = const FAILURE = "Success";
}
print MyClass::SUCCESS;

#静态方法。静态方法不支持$this变量, 因为它们并没有绑定到任何具体的对象：
class MyClass {
    static function helloWorld { print "Hello, world";}
}
MyClass::helloWorld();

#静态成员，可以通过类自身来访问
class Singleton {
    static private $instance = NULL;
    private function __construct{} {}
    static public function getlnstanceO { if (self::$instance == NULL) {
        self::$instance = new SingletonO;
        return self::$instance;
    }
}

#抽象类。把类声明为抽象类可以防止它被实例化。但是你可以继承一个抽象类:
abstract class MyBaseClass { 
    function display() {
        print "Default display routine being called";
    }
}
#抽象方法。把方法声明为抽象的，以便在继承的子类中再去定义。包含抽象方法的类本身必须是一个抽象类：
abstract class MyBaseClass {
    abstract function display();
}

#对象类型提示
#函数声明中可以对参数进行对象类型提示。如果函数调用的时候没有传递正确的对象类型，系统报错：
function expectsMyClass(MyCiass $obj) {}

#多态：使用parent::来调用父类的方法，使用slef::调用当前类的静态方法
class Child extends Ancestor { 
    const NAME = "Child"; 
    function __construct(){
        parent::__construct();
        print self::NAME; 
    }
}
#__toString()函数，类似于Java的toString()

#foreach迭代对象属性，类似于数组迭代
$obj = new Class();
foreach($obj as $key =&gt; $val){
}
#实现接口Iterator可以修改迭代行为</pre>
</div>
<div class="blog_h2"><span class="graybg">接口</span></div>
<pre class="crayon-plain-tag">#接口声明语法
interface IA {
    function m();#不能给原型函数设置访问限定符
}
interface IB extends IA,I{
}
#实现接口的语法
class A implements B, C, ... {
}</pre>
<div class="blog_h2"><span class="graybg">异常处理</span></div>
<pre class="crayon-plain-tag">#try-catch语法
try {
    #会抛出一个异常的代码 
    throw new object();#只能抛出一个Exception类或其子类的实例
} catch (FirstExceptionClass $exception) {
    #异常处理代码
} catch (SecondExceptionClass $exception) {
    #异常处理代码
}
#Exception类的结构
class Exception {
    function __construct([$message [,$code]]);
    final public getMessage();
    final public getCode();
    final public getFile();
    final public getLine();
    final public getTrace();
    final public getTraceAsString();
    
}</pre>
<div class="blog_h2"><span class="graybg">__autoload：自动加载类</span></div>
<div>每个应用只能定义一个__autoload函数，当访问一个不存在的类时，该函数被调用，传递类名为参数<br />
<pre class="crayon-plain-tag">&lt;?php
function _autoload($class_name)
{
    require__once ($_SERVER ["DOCUMENT_ROOT"] . "/classes/$class_name.php";
}
?&gt;</pre>
</div>
<div class="blog_h1"><span class="graybg">第三部分：开发PHP Web应用</span></div>
<div class="blog_h2"><span class="graybg">嵌入PHP代码到HTML文档</span></div>
<pre class="crayon-plain-tag">&lt;?php 
#这是标准嵌入方法
?&gt;
&lt;?/*短代码，某些环境会关闭*/?&gt;
&lt;?=$var?&gt; #等价于&lt;?php echo($var)?&gt;</pre>
<div class="blog_h2"><span class="graybg">获取用户数据</span></div>
<div>$_GET可以得到GET参数，$_POST可以得到POST请求参数</div>
<div>$_REQUEST包含请求的所有数据，包括：$_GET、$_POST、$_COOKIE、$_ENV、$_SERVER，如果这些变量中包含同名的，则按照php.ini的配置进行覆写，后面的覆盖前面的，默认顺序是EGPCS</div>
<div class="blog_h2"><span class="graybg">错误处理</span></div>
<div>
<p>开发期可以设置error_reporting=E_ALL &amp; E_STRICT。通过设置log_errors/display_errors可以控制错误信息的流向，日志文件的位置可以通过error_log指定。可以指定全局错误处理函数：</p>
<pre class="crayon-plain-tag">#type为错误类型，可以是：E_NOTICE、E_WARNING、E_USER_NOTICE、E_USER_WARNING、E_USER_ERROR
#error为错误文本
error_function($type, $error, $file, $line);</pre>
</div>
<div class="blog_h2"><span class="graybg">操控Cookies</span></div>
<pre class="crayon-plain-tag">&lt;?php
    ob_start();//开启输出缓冲，若不开启，则无法正确写入响应头
    //设置Cookie，参数依次：cookie名称、值、过期时间、作用范围，作用范围可以是blog.gmem.cc、.gmem.cc这样的形式
    //删除Cookie，只需要将值设为''，并过期即可
    setcookie('uid', $uid, time()+3600, '/' );
?&gt;</pre>
<div class="blog_h2"><span class="graybg">PHP Session</span></div>
<p>每一个会话使用Session ID识别，该ID由客户端IP、当前时间、一些附加信息散列处理得到</p>
<pre class="crayon-plain-tag">&lt;?php 
    ini_set('session.use_cookies',1);
    ini_set('session.use_only_cookies',1);
    session_start();#必须紧跟ini_set后调用，创建一个session ID，并使用空$_SESSION初始化会话
    $_SESSION['uid'] = $uid;
    header('Location:/index');//重定向
    #销毁会话
    $_SESSION = array();
    session_destroy();
?&gt;</pre>
<div class="blog_h2"><span class="graybg">PHP 文件上传</span></div>
<form action="upload.php" enctype="multipart/form-data" method="POST">
<pre class="crayon-plain-tag">&lt;form enctype="multipart/form-data" action="upload.php" method="POST"&gt;
    &lt;input type="hidden" name="MAX_FILE_SIZE" value="16000" /&gt;
    Select File: &lt;input name="image" type="file"/&gt;
    &lt;input type="submit" value="Upload" /&gt;
&lt;/form&gt;
&lt;?php 
    $img = $_FILES['image'];#该数组存放所有文件上传信息
    print $img['name'];#文件在客户端OS的短名
    print $img['type'];#文件的MIME类型
    print $img['tmp_name'];#在服务器的临时文件名，在请求结束后即被删除
    print $img['error'];#错误代码:0成功,1超过php.ini的upload_max_file设置,2超过表单MAX_FILE_SIZE设置,3只接收到部分文件内容,4没有文件被上传
    print $img['size'];#文件大小
?&gt;</pre><br />
</form>
<div class="blog_h1"><span class="graybg">第四部分：访问数据库</span></div>
<div class="blog_h2"><span class="graybg">使用mysqli接口访问MySQL</span></div>
<div class="blog_h3"><span class="graybg">mysqli函数和方法列表</span></div>
<table class="full-width fixed-word-wrap" style="width: 100%;">
<thead>
<tr>
<td style="width: 35%; text-align: center;"><span style="color: #333333; font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;">函数名</span></td>
<td style="text-align: center;"><span style="color: #333333; font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;">描述</span></td>
</tr>
</thead>
<tbody>
<tr>
<td>
<pre class="crayon-plain-tag">mysqli_connect (...)
$mysqli = new mysqli(...)</pre>
</td>
<td>打开一个连向MySQL服务器的连接. 参数:主机名（string)、用户名（string)、密码（string)、数据库名（string)、TCP端口 (integer)</td>
</tr>
<tr>
<td>
<pre class="crayon-plain-tag">mysqli_init() 
$mysqli = new mysqli() 
mysqli_options(…) 
$mysqli-&gt;options(…) 
mysqli_real_connect(…) 
$mysqli-&gt;real_connect (…)</pre>
</td>
<td>用mysqli_real_connect初始化MySQLi并且返回一个对象<br /> 设置不同的连接选项<br /> 打开一个连向MySQL服务器的连接</td>
</tr>
<tr>
<td>
<pre class="crayon-plain-tag">mysqli_close (...) 
$mysqli-&gt;close ()</pre>
</td>
<td>关闭一个MySQL数据库连接，参数是连接对象（函数方式）</td>
</tr>
<tr>
<td>
<pre class="crayon-plain-tag">mysqli_connect_errno()</pre>
</td>
<td>最后一次失败的连接的错误号</td>
</tr>
<tr>
<td>
<pre class="crayon-plain-tag">mysqli_connect_error()</pre></p>
<p>&nbsp;</p>
</td>
<td>最后一次失败的连接的错误信息</td>
</tr>
<tr>
<td>
<pre class="crayon-plain-tag">mysqli_get_host_info (...)
$mysqli-&gt;host_info</pre>
</td>
<td>返回数据库连接描述信息的字符串</td>
</tr>
<tr>
<td>
<pre class="crayon-plain-tag">mysqli_query(...)</pre>
</td>
<td> 发送一个SQL语句并获得结果集对象，参数：连接（函数方式），SQL，模式（缓冲否）</td>
</tr>
<tr>
<td>
<pre class="crayon-plain-tag">mysqli_multi_query(...)
$mysqli-&gt;multi_query(...)</pre>
</td>
<td> 一次发送并处理多个查询</td>
</tr>
<tr>
<td>
<pre class="crayon-plain-tag">mysqli_fetch_row()
$mysqli-&gt;fetch_row()
mysqli_fetch_assoc(...)
$result-&gt;fetch_assoc()
mysqli_fetch_object(...)
$result-&gt;fetch_object()</pre>
</td>
<td> 抓取结果集行的方式：数组、关联数组、对象</td>
</tr>
<tr>
<td>
<pre class="crayon-plain-tag">mysqli_prepare(...)
$mysqli-&gt;prepare()
mysqli_stmt_bind_result(...)
$stmt-&gt;bind_result(...)
mysqli_stmt_bind_param(...)
$stmt-&gt;bind_ param(...)
mysqli_stmt_execute(...)
$stmt-&gt;execute()
mysqli_stmt_fetch(...)
$stmt-&gt;fetch()
mysqli_stmt_close(...)
$stmt-&gt;close()</pre>
</td>
<td>预编译语句相关的函数prepare：准备一个预编译语句，参数：(连接),SQL语句bind_result：绑定变量到结果集，参数：(语句),变量bind_param：绑定变量到语句，参数：(语句),类型,变量。类型包括：s字符串,i数字,d双字节浮点数,b=blob</p>
<p>execute：执行语句</p>
<p>stmt_fetch：获取数据到输出变量中</p>
<p>stmt_close：关闭预编译语句</p>
</td>
</tr>
</tbody>
</table>
<div class="blog_h3"><span class="graybg">代码示例：</span></div>
<pre class="crayon-plain-tag">&lt;?php
$conn = mysqli_connect("localhost", "username", "passwd", "dbname");
if (empty($conn)) {
    die("mysqli connect failed: " . mysqli_connect_error());
}
// 另外一种风格
$mysqli = new mysqli("localhost", "username", "passwd", "dbname");
$mysqli-&gt;close();
 
// 设置参数
$mysqli = mysqli_init();
$mysqli-&gt;options(MYSQLI_INIT_CMD, "SET_AUTOCOMMIT=0"); // 置初始参数
$mysqli-&gt;options(MYSQLI_READ_DEFAULT_FILE, "SSL_CLIENT");
$mysqli-&gt;options(MYSQLI_OPT_CONNECT_TIMEOUT, 5); // 超时的秒数
$mysqli-&gt;real_connect("localhost", "username", "username", "dbname");
// 执行查询
$result = $conn-&gt;query("SELECT * FROM T_USER", MYSQLI_USE_RESULT); // 二个参数表示使用无缓冲
while ($row = $result-&gt;fetch_row()) {
    print $row[0];
}
$result-&gt;free(); // 关闭结果集
                 
// 预编译语句，
$stmt = $conn-&gt;prepare("INSERT INTO T_USER VALUES(?, ?)");
#绑定输入参数
$stmt-&gt;bind_param($name, $dob, $age);
$name = "Alex";$dob = "1986";$age = "29";
$stmt-&gt;execute();
$name = "Meng";$dob = "1989";$age = "26";
$stmt-&gt;execute();
 
#绑定输出变量
$stmt-&gt;bind_result($name,$dob,$age);
while ($stmt-&gt;fetch()) {
    print "$name: $dob";
}
#处理BLOG数据的方式和普通数据一样
?&gt;</pre>
<div class="blog_h2"><span class="graybg">通用数据库访问抽象层：PEAR DB</span></div>
<p>支持大多数的数据库，提供统一风格的API</p>
<div class="blog_h1"><span class="graybg">第五部分：错误处理</span></div>
<div class="blog_h2"><span class="graybg">错误类型</span></div>
<table class=" fixed-word-wrap full-width">
<thead>
<tr>
<td style="width: 25%; text-align: center;">类型</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>编程错误</td>
<td>语法错误：在PHP执行前被检测到，例如：<pre class="crayon-plain-tag">Parse error: parse error in test.php on line 4</pre> <br />Include/Require：错误之后的代码被废弃，得到不完整编译的文件（后续代码未定义）</td>
</tr>
<tr>
<td>未定义符号</td>
<td>未定义变量、常量：错误通常以警告形式出现<br />未定义函数、类：中止执行，例如：<pre class="crayon-plain-tag">Fatal error: Call to undefined function： undefined_this_function_is()</pre> </td>
</tr>
<tr>
<td>通用类错误</td>
<td>php.ini的配置差异：使用ini_get()检查<br />SAPI差异：例如Apache专有函数</td>
</tr>
<tr>
<td>运行时错误</td>
<td>通常不是编程错误，例如硬盘故障、网络故障。由错误报告机制或者异常处理机制负责处理</td>
</tr>
</tbody>
</table>
<div class="blog_h2"><span class="graybg">PHP错误</span></div>
<div class="blog_h3"><span class="graybg">错误报告级别</span></div>
<table class=" full-width fixed-word-wrap">
<thead>
<tr>
<td style="width: 25%; text-align: center;">错误级别</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>E_ERROR</td>
<td>严重的不可恢复的错误，例如内存不足、类重复声明</td>
</tr>
<tr>
<td>E_WARNING</td>
<td>例如数据库连接失败、除0错误</td>
</tr>
<tr>
<td>E_PARSE</td>
<td>该错误在编译时发生，会强制PHP在执行前退出</td>
</tr>
<tr>
<td>E_NOTICE</td>
<td>一般性通知，建议开发期开启</td>
</tr>
<tr>
<td>E_CORE_ERROR</td>
<td>该内部PHP错误是由于扩展启动失败导致的，而且会导致PHP运行退出</td>
</tr>
<tr>
<td>E_USER_ERROR</td>
<td>用户生成的致命错误，可以通过<pre class="crayon-plain-tag">trigger_error()</pre>  生成</td>
</tr>
<tr>
<td>E_USER_WARNING</td>
<td>用户生成的警告，可以通过trigger_error() 生成</td>
</tr>
<tr>
<td>E_USER_NOTICE</td>
<td>用户生成的一般性通知，可以通过trigger_error() 生成</td>
</tr>
<tr>
<td>E_ALL</td>
<td>所有错误和警告，除级别 E_STRICT 以外</td>
</tr>
</tbody>
</table>
<div class="blog_h3"><span class="graybg">错误报告配置</span></div>
<p>php.ini的一些配置项控制哪些错误显示，以及如何显示：</p>
<table class=" full-width fixed-word-wrap" style="width: 100%;">
<thead>
<tr>
<td style="width: 150px; text-align: center;">配置项</td>
<td style="width: 100px; text-align: center;">数据类型</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>error_reporting</td>
<td>整型</td>
<td>设置默认错误报告方式，例如：E_ALL，E_ALL &amp; ~E_NOTICE(除了NOTICE级别的所有错误被报告)。0表示任何错误都不报告</td>
</tr>
<tr>
<td>display_errors</td>
<td>布尔型</td>
<td>控制错误是否作为PHP输出的一部分显示出来。它默认设置为On</td>
</tr>
<tr>
<td>display_startup_errors</td>
<td>布尔型</td>
<td>这个设置控制在PHP启动时是否显示错误。它的默认设置是Off</td>
</tr>
<tr>
<td>error_prepend_string</td>
<td>字符串</td>
<td>这个字符串将在浏览器中显示错误信息之前直接显示出来</td>
</tr>
<tr>
<td>error_append_string</td>
<td>字符串</td>
<td>这个字符串将在浏览器中显示错误信息之后直接显示出来</td>
</tr>
<tr>
<td>track_errors</td>
<td>布尔型</td>
<td>开启时，$php_errormsg在脚本中可见，包含错误信息</td>
</tr>
<tr>
<td>html_errors</td>
<td>布尔型</td>
<td>是否在错误信息中采用HTML格式，默认On，CLI版本PHP除外</td>
</tr>
<tr>
<td>xmlrpc_errors</td>
<td>布尔型</td>
<td>错误信息是否作为XML-RPC故障显示</td>
</tr>
<tr>
<td>xmlrpc_error_number</td>
<td>整型</td>
<td>配合xmlrpc_errors</td>
</tr>
<tr>
<td> log_errors</td>
<td>布尔型</td>
<td>是否记录错误日志到文件系统，默认记录到Web服务器的错误日志中</td>
</tr>
<tr>
<td> error_log</td>
<td>字符串</td>
<td>日志文件的位置，指定syslog则记录到系统日志（Unix）</td>
</tr>
<tr>
<td> log_errors_max_len</td>
<td>整型</td>
<td>日志信息最大长度，超过的被截断</td>
</tr>
<tr>
<td>ignore_repeated_errors</td>
<td>布尔型</td>
<td>重复的错误是否被显示</td>
</tr>
<tr>
<td>ignore_repeated_source</td>
<td>布尔型</td>
<td>来自同一文件同一行的错误是否被显示</td>
</tr>
</tbody>
</table>
<p>配置文件样例如下：</p>
<pre class="crayon-plain-tag">; 开发环境的典型配置
error_reporting = E_ALL 
display_errors = on 
html_errors = on 
log_errors = off
; 生产环境的典型配置
error_reporting = E_ALL &amp; ~E_NOTICE 
display_errors = off 
log_errors = on 
html_errors = off
error_log = "/var/log/php-error.log"
ignore_repeated_errors = on 
ignore_repeated_source = on</pre>
<div class="blog_h3"><span class="graybg">自定义错误处理器</span></div>
<p>可以定义一个函数，在每一个错误出现时调用：</p>
<pre class="crayon-plain-tag">function customErrorHandler ($errno, $errstr) {
    echo "&lt;b&gt;Error:&lt;/b&gt; [$errno] $errstr&lt;br /&gt;";
    echo "Ending Script";
    die();
}

set_error_handler("customErrorHandler");</pre>
<div class="blog_h3"><span class="graybg">错误抑制</span></div>
<p>在语句前加上符号@，则该语句的错误级别为0。只有内置的错误报告和日志记录受@影响，自定义错误处理器继续工作：</p>
<pre class="crayon-plain-tag">&lt;?php
if (@$_GET["id"]) {
    $obj = new MyDataObject();
}
?&gt;</pre>
<div class="blog_h2"><span class="graybg">PEAR错误</span></div>
<p>PEAR组件使用单独的错误机制，通过检查返回值来判断异常。</p>
<div class="blog_h2"><span class="graybg">异常处理</span></div>
<p>PHP5提供了新的，面向对象的try-catch机制来捕获和处理异常，异常必须是Exception类的子类型。下面的代码示例了异常的常规用法：</p>
<pre class="crayon-plain-tag">function checkAge ($age) {
    if ($age &lt; 0) {
        // 抛出异常
        throw new Exception('Invalid age.');
    }
}
// 捕获异常
try {
    checkAge(- 2);
} catch (Exception $e) {
    echo 'Error: ' . $e-&gt;getMessage();
}

// 自定义异常类
class InvalidAgeException extends Exception {

    public function setMessage ($message) {
        $this . $message = $message;
    }
}</pre>
<div class="blog_h3"><span class="graybg">设置顶层异常处理器</span></div>
<p>任何未捕获的异常，可以由顶层异常处理器负责处理：</p>
<pre class="crayon-plain-tag">function customExceptionHandler ($exception) {
    echo "Exception: " . $exception-&gt;getMessage();
}
// 设置处理器
set_exception_handler('customExceptionHandler');

// 下面的异常没有被捕获，讲传递给顶层异常处理器
throw new Exception('Uncaught Exception occurred');</pre>
<div class="blog_h1"><span class="graybg">第六部分：XML处理</span></div>
<div class="blog_h2"><span class="graybg">解析XML</span></div>
<div class="blog_h3"><span class="graybg">SAX(Simple API for XML)：事件驱动</span></div>
<pre class="crayon-plain-tag"><!--?php 
$xml = xml_parser_create('UTF-8'); // XML编码方式
xml_set_element_handler($xml, 'start_handler', 'end_handler'); // 开始、结束标签处理器
xml_set_character_data_handler($xml, 'character_handler'); // 文本内容处理器
xml_parser_set_option($xml, XML_0PTION_CASE_FOLDING, false); // 禁用标签名全大写转换
function start_handler ($xml, $tag, $attributes)
{
    global $level; // 标签嵌套层次
    echo " \n" . str_repeat(' ', $level) . " $tag";
    foreach ($attributes as $key =--> $value) {
        echo "$key $value";
    }
    $level ++;
}
function end_handler ($xml, $tag)
{
    global $level;
    $level --;
    echo str_repeat(' ', $level, ' ') . " $tag";
}
function character_handler ($xml, $data)
{}
xml_parse($xmly, file_get_contents("test.xml")); // 执行解析
?&gt;</pre>
<div class="blog_h3"><span class="graybg">DOM：解析为文档树</span></div>
<p>该方式的缺点是内存消耗大</p>
<pre class="crayon-plain-tag">&lt;?php
$dom = new DomDocument();
$dom-&gt;load('test.xml');
$root = $dom-&gt;documentElement;
process_children($root);
 
function process_children ($node)
{
    $children = $node-&gt;childNodes;
    foreach ($children as $elem) {
        if ($elem-&gt;nodeType == XML_TEXT_NODE) {
            if (strlen(trim($elem-&gt;nodeValue))) {
                echo trim($elem-&gt;nodeValue), "\n";
            }
        } else 
            if ($elem-&gt;nodeType == XML_ELEMENT_NODE) {
                process_children($elem);
            }
    }
}
?&gt;</pre>
<div class="blog_h3"><span class="graybg">SimpleXML</span></div>
<p>SimpleXML扩展在PHP5默认开启，该方式处理XML最简单，直接通过数据结构的形式访问XML节点：<br /> 1、属性导航表示子元素的迭代器，例如：mother-&gt;children得到孩子的迭代器<br /> 2、数字索引表示第N个子元素，例如：mother-&gt;children[1]访问第二个孩子<br /> 3、非数字索引表示XML属性，例如：mother['name']得到母亲的名字<br /> 4、元素可以直接作为字符串使用(_toString)，以访问其文本内容（不包括子元素）</p>
<pre class="crayon-plain-tag">&lt;?php
$sx0 = simplexml_load_file('test.xml'); // 通过文件读取
$sx1 = simplexml_load_dom(new DomDocument()); // 通过DOM对象读取
 
$str = &lt;&lt;&lt;XML
&lt;?xml version='1.0'?&gt;
&lt;html xmlns="http：//www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
    &lt;head&gt;
        &lt;title&gt;XML&lt;/title&gt;
    &lt;/head&gt;
    &lt;body bgcolor="#FFF"&gt;
        &lt;div&gt;Hello &lt;span&gt;XML&lt;/span&gt;&lt;/div&gt;
        &lt;div&gt;&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;
XML;
 
$html = simplexml_load_string($str); // 从字符串读取
foreach ($html-&gt;body-&gt;div as $div) {
    $div-&gt;span[0];
    $div['bgcolor'];
    echo $div; // 输出文本内容
    echo strip_tags($div-&gt;asXML()); // 输出完整文本
}
file_put_contents('test.xml', $html-&gt;asXML());
?&gt;</pre>
</div><p>The post <a rel="nofollow" href="https://blog.gmem.cc/php5-study-note">PHP5学习笔记</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.gmem.cc/php5-study-note/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
