<?xml version="1.0" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="css/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>郑州网建 - PHP_Python</title><link>http://camnpr.com/</link><description>Good Good Study ,Day Day Up! - </description><generator>RainbowSoft Studio Z-Blog 1.8 Walle Build 100427</generator><language>zh-CN</language><copyright>豫ICP备10013645号 Copyright 2009-2022 camnpr.com</copyright><pubDate>Sat, 07 Mar 2026 06:07:06 +0800</pubDate><item><title>简介腾讯CMEM的PHP扩展编译安装方法</title><author>camnpr@163.com (佚名)</author><link>http://camnpr.com/php-python/2253.html</link><pubDate>Tue, 01 Mar 2016 10:04:00 +0800</pubDate><guid>http://camnpr.com/php-python/2253.html</guid><description><![CDATA[<p>CMEM是什么？</p><p>CMEM全称为Cloud Memory，是腾讯提供的高性能内存级持久化存储服务，适用于数据量小、访问量高、key-value存储的场景。</p><p>CMEM基于一个存储键/值对的hashmap，数据使用内存存储，并保证数据的持久性。</p><p>CMEM PHP Extension是什么？</p><p>CMEM基于标准的Memcached协议以及接口，只是将数据获取接口增加返回值设定。<br />Memcached的Get协议没有设计返回码，所以Memcached API返回NO_DATA时，有可能是网络原因造成的，不能完全信任。 使用如下流程将是非常危险的，将造成用户数据初始化：</p><pre class="brush:php;">if(NO_DATA) {<br />  InitData();<br />}</pre><p>为解决上述问题，CMEM提供了Memcahced文本扩展协议，增加两个扩展的命令get_ext， gets_ext，使客户端可以根据返回码判断数据是否存在。 这样可以避免网络和设备故障时get不到数据而导致用户数据被误初始化。</p><p>CMEM编译与安装</p><pre class="brush:php;"># 下载CMEM<br />cd /home/src<br />wget http://cmem.googlecode.com/files/cmem-2.2.6.tar.gz<br /># 解压<br />tar zxvf cmem-2.2.6.tar.gz<br />cd cmem-2.2.6<br /># 编译<br />/usr/local/webserver/php/bin/phpize<br />./configure --with-php-config=/usr/local/webserver/php/bin/php-config<br />make<br /># 安装PHP扩展<br />cp modules/cmem.so /usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20090626/<br /># 配置php.ini<br /># 加入以下内容<br /># --------------------------------------------------<br />extension = &quot;cmem.so&quot;<br /># --------------------------------------------------<br /># 测试<br /># 新建cmemtest.php<br />cat &gt; /tmp/cmemtest.php<br /># 代码为<br /># --------------------------------------------------<br />&lt;?php<br />if(!class_exists('CMEM')) echo &quot;CMEM NOT FOUND!\n&quot;;<br />else echo &quot;CMEM IS OK\n&quot;;<br />?&gt;<br /># --------------------------------------------------<br /># 执行测试文件<br />/usr/local/webserver/php/bin/php -f /tmp/cmemtest.php</pre>]]></description><category>PHP_Python</category><comments>http://camnpr.com/php-python/2253.html#comment</comments><wfw:comment>http://camnpr.com/</wfw:comment><wfw:commentRss>http://camnpr.com/feed.asp?cmt=2253</wfw:commentRss><trackback:ping>http://camnpr.com/cmd.asp?act=tb&amp;id=2253&amp;key=98b3de4d</trackback:ping></item><item><title>总结三种PHP生成随机字符串的方法</title><author>camnpr@163.com (佚名)</author><link>http://camnpr.com/php-python/2252.html</link><pubDate>Fri, 26 Feb 2016 10:23:34 +0800</pubDate><guid>http://camnpr.com/php-python/2252.html</guid><description><![CDATA[<p><strong>方法一</strong></p><p>1、在33 &ndash; 126中生成一个随机整数，如35。</p><p>2、将35转换成对应的ASCII码字符，如35对应#。</p><p>3、重复以上1、2步骤n次，连接成n位的密码。</p><p>该算法主要用到了两个函数，mt_rand ( int $min , int $max )函数用于生成随机整数，其中 $min &ndash; $max 为 ASCII 码的范围，这里取 33 -126 ，可以根据需要调整范围，如ASCII码表中 97 &ndash; 122 位对应 a &ndash; z 的英文字母，具体可参考 ASCII码表； chr ( int $ascii )函数用于将对应整数 $ascii 转换成对应的字符。</p><pre class="brush:php;">function create_password($pw_length =  <br />{ <br />$randpwd = &rdquo;; <br />for ($i = 0; $i &lt; $pw_length; $i++) <br />{ <br />$randpwd .= chr(mt_rand(33, 126)); <br />} <br />return $randpwd; <br />} <br />// 调用该函数，传递长度参数$pw_length = 6 <br />echo create_password(6); </pre><p><strong>方法二</strong></p><p>1、预置一个的字符串 $chars ，包括 a &ndash; z，A &ndash; Z，0 &ndash; 9，以及一些特殊字符。</p><p>2、在 $chars 字符串中随机取一个字符。</p><p>3、重复第二步n次，可得长度为n的密码。</p><pre class="brush:php;">function generate_password( $length = 8 ) { <br />// 密码字符集，可任意添加你需要的字符 <br />$chars = &lsquo;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&amp;*()-_ []{}&lt;&gt;~`+=,.;:/?|'; <br />$password = &rdquo;; <br />for ( $i = 0; $i &lt; $length; $i++ ) <br />{ <br />// 这里提供两种字符获取方式 <br />// 第一种是使用 substr 截取$chars中的任意一位字符； <br />// 第二种是取字符数组 $chars 的任意元素 <br />// $password .= substr($chars, mt_rand(0, strlen($chars) &ndash; 1), 1); <br />$password .= $chars[ mt_rand(0, strlen($chars) - 1) ]; <br />} <br />return $password; <br />} </pre><p><strong>方法三</strong></p><p>1、预置一个的字符数组 $chars ，包括 a &ndash; z，A &ndash; Z，0 &ndash; 9，以及一些特殊字符。</p><p>2、通过array_rand()从数组$chars中随机选出$length个元素。</p><p>3、根据已获取的键名数组 $keys，从数组$chars取出字符拼接字符串。该方法的缺点是相同的字符不会重复取。</p><pre class="brush:php;">function make_password( $length = 8 ) <br />{ <br /> <br />// 密码字符集，可任意添加你需要的字符 <br />$chars = array(&lsquo;a', &lsquo;b', &lsquo;c', &lsquo;d', &lsquo;e', &lsquo;f', &lsquo;g', &lsquo;h', <br />&lsquo;i', &lsquo;j', &lsquo;k', &lsquo;l','m', &lsquo;n', &lsquo;o', &lsquo;p', &lsquo;q', &lsquo;r', 's', <br />&lsquo;t', &lsquo;u', &lsquo;v', &lsquo;w', &lsquo;x', &lsquo;y','z', &lsquo;A', &lsquo;B', &lsquo;C', &lsquo;D', <br />&lsquo;E', &lsquo;F', &lsquo;G', &lsquo;H', &lsquo;I', &lsquo;J', &lsquo;K', &lsquo;L','M', &lsquo;N', &lsquo;O', <br />&lsquo;P', &lsquo;Q', &lsquo;R', &lsquo;S', &lsquo;T', &lsquo;U', &lsquo;V', &lsquo;W', &lsquo;X', &lsquo;Y','Z', <br />&lsquo;0&prime;, &lsquo;1&prime;, &lsquo;2&prime;, &lsquo;3&prime;, &lsquo;4&prime;, &lsquo;5&prime;, &lsquo;6&prime;, &lsquo;7&prime;, &lsquo;8&prime;,<br /> &lsquo;9&prime;, &lsquo;!', <br />&lsquo;@','#', &lsquo;$', &lsquo;%', &lsquo;^', &lsquo;&amp;', &lsquo;*', &lsquo;(&lsquo;, &lsquo;)', &lsquo;-', &lsquo;_', <br />&lsquo;[', ']&lsquo;, &lsquo;{&lsquo;, &lsquo;}', &lsquo;&lt;', &lsquo;&gt;', &lsquo;~', &lsquo;`', &lsquo;+', &lsquo;=', &lsquo;,', <br />&lsquo;.', &lsquo;;', &lsquo;:', &lsquo;/', &lsquo;?', &lsquo;|'); <br /> <br />// 在 $chars 中随机取 $length 个数组元素键名 <br />$keys = ($chars, $length); <br />$password = &rdquo;; <br />for($i = 0; $i &lt; $length; $i++) <br />{ <br />// 将 $length 个数组元素连接成字符串 <br />$password .= $chars[$keys[$i]]; <br />} <br />return $password; <br />} </pre><p><strong><span style="color: #ff0000;" data-mce-style="color: #ff0000;">时间效率对比</span></strong></p><p>我们使用以下PHP代码，计算上面的3 个随机密码生成函数生成6 位密码的运行时间，进而对他们的时间效率进行一个简单的对比。最终得出的结果是：</p><p><strong>方法一：9.8943710327148E-5 秒&nbsp; <br />方法二：9.6797943115234E-5 秒&nbsp; <br />方法三：0.00017499923706055 秒 <br /></strong>可以看出方法一和方法二的执行时间都差不多，而方法三的运行时间稍微长了点。<br />通过比较三种方法的实现过程，时间效率对比，学习了PHP生成随机字符串的三种方法.</p><p>如用户注册生成随机密码，用户重置密码也需要生成一个随机的密码。随机密码也就是一串固定长度的字符串，文章整理了几种生成随机字符串的方法。</p>]]></description><category>PHP_Python</category><comments>http://camnpr.com/php-python/2252.html#comment</comments><wfw:comment>http://camnpr.com/</wfw:comment><wfw:commentRss>http://camnpr.com/feed.asp?cmt=2252</wfw:commentRss><trackback:ping>http://camnpr.com/cmd.asp?act=tb&amp;id=2252&amp;key=d1c23ccf</trackback:ping></item><item><title>PHP反盗链的设置方法和防盗链的基本思想 </title><author>camnpr@163.com (佚名)</author><link>http://camnpr.com/php-python/2251.html</link><pubDate>Wed, 24 Feb 2016 10:45:31 +0800</pubDate><guid>http://camnpr.com/php-python/2251.html</guid><description><![CDATA[<p>盗链是指服务提供商自己不提供服务的内容，通过技术手段绕过其它有利益的最终用户界面(如广告)，直接在自己的网站上向最终用户提供其它服务提供商的服务内容，骗取最终用户的浏览和点击率。受益者不提供资源或提供很少的资源，而真正的服务提供商却得不到任何的收益。做好防止盗链的工作，是每个网站开发者的重要工作。</p><p>做好防盗链工作能给网站服务器减少不少压力，这里我们分享一种php防盗链的实现方法：</p><p><strong>一般的下载的步骤：查找－＞输出查找结果列表－＞进入软件详细页面－＞点击下载按钮－＞打开下载页面-&gt;点击下载，开始下载</strong></p><p><strong>我的方法就是在下载页面做文章</strong></p><p>首先在网站的公共文件里定义一个$key=sdkfjwojf32413这相当于一个密钥一样</p><p>在下载页面生成一个随机数：$certcode = '84615354' (每次打开生成的都不一样)</p><p>然后用以上两个变量和软件的ID生成一个md5()加密串</p><p>然后生成软件的真实下载地址：file.php?id=5&amp;codekey=ksfjwofsdkfsf</p><p>这里的id是软件的编号可以根据他从数据库找到软件地址　$codekey＝md5($id.$certcode.$key) <br />然后把certcode保存到session里，</p><p>在file.php的参数里面得到的codekey和id再从公共文件里得到$key 再从session里得到$certcode</p><p>对codekey进么验证，看是否正确，如果不正确就退出，否则就进行如下操作</p><p>1、删除session(再次打开这个地址就无效了)</p><p>2、从数据库里读取软件地址，然后读取软件内容，并输出（用ＰＨＰ的文件读取方法输出要下载的软件内容而不是直接把地址给他下载）</p><p>这样如果要下载，就必须打开你自己的下载页面，从你的下载页面打开地址才能进行下载，而且下载地址每次都不一样，因为生成的随机数不一样</p><p>别的地方就算连到你的下载地址，也是下载不了的。</p><p>拓展阅读（具体实现）：</p><p><strong>1.简单防盗链</strong></p><pre class="brush:xhtml;">$ADMIN[defaulturl] = &quot;http://www.camnpr.com/404.htm&quot;;//盗链返回的地址 <br />$okaysites = array(&quot;http://www.camnpr.com/&quot;,&quot;http://www.bubuol.com&quot;); //白名单 <br />$ADMIN[url_1] = &quot;http://www.camnpr.com/temp/download/&quot;;//下载地点1 <br />$ADMIN[url_2] = &quot;&quot;;//下载地点2，以此类推 <br /> <br />$reffer = $HTTP_REFERER; <br />if($reffer) { <br />$yes = 0; <br />while(list($domain, $subarray) = each($okaysites)) { <br />if (ereg($subarray,&quot;$reffer&quot;)) { <br />$yes = 1; <br />} <br />} <br />$theu = &quot;url&quot;.&quot;_&quot;.&quot;$site&quot;; <br />if ($ADMIN[$theu] AND $yes == 1) { <br />header(&quot;Location: $ADMIN[$theu]/$file&quot;); <br />} else { <br />header(&quot;Location: $ADMIN[defaulturl]&quot;); <br />} <br />} else { <br />header(&quot;Location: $ADMIN[defaulturl]&quot;); <br />}?&gt; </pre><p>使用方法:将上述代码保存为dao4.php,比如我测试用的validatecode.rar在我的站点里面,则用以下代码表示下载连接.</p><p>文件名?site=1&amp;file=文件</p><p><strong>2.服务器防盗链</strong></p><p><strong>3.软件下载的防盗链方法</strong></p><pre class="brush:php;">//放置下载软件的根目录相对于当前脚本目录的相对目录 <br />$fileRelPath = &quot;../../software&quot;; <br />//例外允许连接的网址，注意:自身域名不需要填入,设定为肯定可以下载, <br />// 空字符串(&quot;&quot;)表示直接输入网址下载的情况 <br />$excludeReferArr = array(&quot;www.camnpr.com&quot;, &quot;camnpr.com&quot;); <br />chdir($fileRelPath); <br />$fileRootPath = getcwd() .&quot;/&quot;; <br />$filePath=$HTTP_GET_VARS[&quot;file&quot;]; <br />$url=parse_url($_SERVER[&quot;HTTP_REFERER&quot;]); <br />if($url[host]!=$_SERVER[&quot;HTTP_HOST&quot;] &amp;&amp; !in_array($referHost, $excludeReferArr)){ <br />?&gt; </pre><p>其实，反盗链方式也有不少, 这里只列出一个大概思想作为参考：</p><p>（1）IIS 反盗链, 利用ISAPI_Rewrite,可作为Windows下反盗链的一个解决方案；</p><p>（2） 图片反盗链，在图片中加入水印，虽然盗链者可以达到目的，但是却也在为自己的网站做宣传。</p>]]></description><category>PHP_Python</category><comments>http://camnpr.com/php-python/2251.html#comment</comments><wfw:comment>http://camnpr.com/</wfw:comment><wfw:commentRss>http://camnpr.com/feed.asp?cmt=2251</wfw:commentRss><trackback:ping>http://camnpr.com/cmd.asp?act=tb&amp;id=2251&amp;key=61974bd1</trackback:ping></item><item><title>收藏十个PHP高级应用技巧（绝对实用）</title><author>camnpr@163.com (佚名)</author><link>http://camnpr.com/php-python/2250.html</link><pubDate>Tue, 23 Feb 2016 09:53:57 +0800</pubDate><guid>http://camnpr.com/php-python/2250.html</guid><description><![CDATA[<div id="noimgcss"><p>PHP 独特的语法混合了 C、Java、Perl 以及 PHP 自创新的语法。它可以比 CGI或者Perl更快速的执行动态网页。用PHP做出的动态页面与其他的编程语言相比，PHP是将程序嵌入到HTML文档中去执行，执行效率比完全生成HTML标记的CGI要高许多。下面介绍了十个PHP高级应用技巧。</p><p style="text-align: center;" data-mce-style="text-align: center;"><img src="http://camnpr.com/upload/2016/2/201602230955068150.jpg" alt="PHP" /></p><p><strong>1, 使用ip2long() 和 long2ip() 函数来把 IP 地址转化成整型存储到数据库里。</strong></p><p>这种方法把存储空间降到了接近四分之一（char(15) 的 15 个字节对整形的 4 个字节），计算一个特定的地址是不是在一个区段内页更简单了，而且加快了搜索和排序的速度（虽然有时仅仅是快了一点）。</p><p><strong>2, 在验证 email 地址的时候使用 checkdnsrr() 函数验证域名是否存在。</strong></p><p>这个内置函数能够确认指定的域名能够解析成 IP 地址。该函数的PHP 文档的用户评论部分有一个简单的用户自定义函数，这个函数基于 checkdnsrr()，用来验证 email 地址的合法性。对于那些认为自己的 email 地址是 [url=mailto:&ldquo;joeuser@wwwphp.net]&ldquo;joeuser@wwwphp.net[/url]&rdquo; 而不是 [url=mailto:&ldquo;joeuser@php.net]&ldquo;joeuser@php.net[/url]&rdquo; 的家伙们，这个方法可以很方便的抓住他们。</p><p><strong>3, 如果你使用的是 PHP 5 和 MySQL 4.1 或者更高的版本，考虑抛弃 mysql_* 系列函数改用改进版的 mysqli_* 系列函数。</strong></p><p>一个很好的功能就是你可以使用预处理语句，如果你在维护一个数据库密集型站点，这个功能能够加快查询速度。一些评估分数。</p><p><strong>4, 学会爱上三元运算符。</strong></p><p><strong>5, 如果你在项目中感觉到有可复用的部分，在你写下一行代码前先看看 PEAR 中是否已经有了。</strong></p><p>很多 PHP 程序员都知道 PEAR 是一个很好的资源库，虽然还有很多程序员不知道。这个在线资源库包含了超过 400 个可以复用的程序片段，这些程序片段你可以立即用刀你的程序里。除非说你的项目真的是非常特别的，你总能找到帮你节省时间的 PEAR 包。（参见 PECL）</p><p><strong>6, 用 highlight_file() 来自动的打印出格式化的很漂亮的源代码。</strong></p><p>如果你在留言板、IRC 这些地方寻求一个脚本的帮助的话，这个函数用起来非常的顺手。当然了，要小心不要意外的泄露出你的数据库连接信息和密码等。</p><p><strong>7, 使用 error_reporting(0) 函数来防止用户看到潜在的敏感错误信息。</strong></p><p>在理想情况下，发布服务器应该在 php.ini 里完全禁止。但是如果你用的是一个共享的 web 服务器的话，你没有自己的 php.ini 文件，那么这种情况下你最好的选择就是在所有脚本的第一行前加上 error_reporting(0);（或者使用 require_once() 方法）。这就能够在出错的时候完全屏蔽敏感的 SQL 查询语句和路径名。</p><p><strong>8, 在网数据库中存储很大的字符串之前使用 gzcompress() 和 gzuncompress() 来显式的压缩/解压字符串。</strong></p><p>这个 PHP 内置函数使用 gzip 算法，可以压缩普通文本达 90%。在我每次要读写 BLOB 类型的字段的时候都使用这些函数。唯一额例外就是当我需要全文检索的时候。</p><p><strong>9, 通过&ldquo;引用&rdquo;传递参数的方法从一个函数中得到多个返回值。</strong></p><p>就像三元运算符一样，大部分受过正式编程训练的程序员都知道这个技巧。但是那些 HTML 背景大于 Pascal 背景的程序员都或多或少的有过这样的疑问&ldquo;在仅能使用一次 return 的情况下，从一个函数里返回多个值？&rdquo;答案就是在变量前加上一个 &ldquo;&amp;&rdquo; 符号，通过&ldquo;引用&rdquo;传递而非&ldquo;值&rdquo;传递。</p><p><strong>10, 完全理解&ldquo;魔术引号&rdquo;和 SQL 注入的危险性。</strong></p><p>我希望阅读到这里的开发者都已经很对 SQL 注入和了解了。不过我还是把这条列在这里，是因为这个确实有点难以理解。如果你还没有听说过这种说法，那么把今天剩下的时间都用来Google、阅读吧。</p><p>通过本文的分析，希望对你有帮助，牢记这十个PHP非常实用的高级应用技巧，必有收获。</p></div>]]></description><category>PHP_Python</category><comments>http://camnpr.com/php-python/2250.html#comment</comments><wfw:comment>http://camnpr.com/</wfw:comment><wfw:commentRss>http://camnpr.com/feed.asp?cmt=2250</wfw:commentRss><trackback:ping>http://camnpr.com/cmd.asp?act=tb&amp;id=2250&amp;key=12d62bcb</trackback:ping></item><item><title>PHP中如何使用Session对象及与Cookie的关系</title><author>camnpr@163.com (佚名)</author><link>http://camnpr.com/php-python/2249.html</link><pubDate>Mon, 22 Feb 2016 10:12:32 +0800</pubDate><guid>http://camnpr.com/php-python/2249.html</guid><description><![CDATA[<p>在PHP开发中对比起Cookie，session 是存储在服务器端的会话，相对安全，并且不像 Cookie 那样有存储长度限制。下面则是对Session的介绍。</p><p><strong>php中的Session与Cookie</strong></p><p>在PHP开发中对比起Cookie，session 是存储在服务器端的会话，相对安全，并且不像 Cookie 那样有存储长度限制，本文简单介绍 session 的使用。</p><p>由于 Session 是以文本文件形式存储在服务器端的，所以不怕客户端修改 Session 内容。实际上在服务器端的 Session 文件，PHP 自动修改 session 文件的权限，只保留了系统读和写权限，而且不能通过 ftp 修改，所以安全得多。</p><p>对于 Cookie 来说，假设我们要验证用户是否登陆，就必须在 Cookie 中保存用户名和密码(可能是 md5 加密后字符串)，并在每次请求页面的时候进行验证。如果用户名和密码存储在数据库，每次都要执行一次数据库查询，给数据库造成多余的负担。因为我们并不能只做一次验证。为什么呢?因为客户端 Cookie 中的信息是有可能被修改的。假如你存储 $admin 变量来表示用户是否登陆，$admin 为 true 的时候表示登陆，为 false 的时候表示未登录，在第一次通过验证后将 $admin 等于 true 存储在 Cookie，下次就不用验证了，这样对么?错了，假如有人伪造一个值为 true 的 $admin 变量那不是就立即取的了管理权限么?非常的不安全。</p><p>而 Session 就不同了，Session 是存储在服务器端的，远程用户没办法修改 session 文件的内容，因此我们可以单纯存储一个 $admin 变量来判断是否登陆，首次验证通过后设置 $admin 值为 true，以后判断该值是否为 true，假如不是，转入登陆界面，这样就可以减少很多数据库操作了。而且可以减少每次为了验证 Cookie 而传递密码的不安全性了(session 验证只需要传递一次，假如你没有使用 SSL 安全协议的话)。即使密码进行了 md5 加密，也是很容易被截获的。</p><p>当然使用 session 还有很多优点，比如控制容易，可以按照用户自定义存储等(存储于数据库)。我这里就不多说了。</p><p>session 在 php.ini 是否需要设置呢?一般不需要的，因为并不是每个人都有修改 PHP.ini 的权限，默认 session 的存放路径是服务器的系统临时文件夹，我们可以自定义存放在自己的文件夹里，这个稍后我会介绍。</p><p><strong>Php如何创建Session</strong></p><p>开始介绍如何创建 session。非常简单，真的。</p><p>启动 session 会话，并创建一个 $admin 变量：</p><pre class="brush:php;">// 启动 session session_start(); <br>// 声明一个名为 admin 的变量，并赋空值。 <br>$_session["admin"] = null; <br>?&gt; 　 </pre><p>如果你使用了 Session，或者该 PHP 文件要调用 Session 变量，那么就必须在调用 Session 之前启动它，使用 session_start() 函数。其它都不需要你设置了，PHP 自动完成 session 文件的创建。</p><p>执行完这个程序后，我们可以到系统临时文件夹找到这个 session 文件，一般文件名形如：sess_4c83638b3b0dbf65583181c2f89168ec，后面是 32 位编码后的随机字符串。用编辑器打开它，看一下它的内容：</p><pre class="brush:php;">admin|N; </pre><p><strong>一般内容结构：</strong></p><p>变量名|类型:长度:值;</p><p>并用分号隔开每个变量。有些是可以省略的，比如长度和类型。</p><p>我们来看一下验证程序，假设数据库存储的是用户名和 md5 加密后的密码：</p><pre class="brush:php;">// 表单提交后... 　 <br>$posts = $_POST; <br>// 清除一些空白符号 <br>foreach ($posts as $key =&gt; $value) <br>{ <br>$posts[$key] = trim($value); <br>} <br>$password = md5($posts["password"]); <br>$username = $posts["username"]; <br>$query = "SELECT `username` FROM `user` WHERE `password` = '$password'"; <br>// 取得查询结果 <br>$userInfo = $DB-&gt;getRow($query); <br>if (!emptyempty($userInfo)) <br>{ <br>if ($userInfo["username"] == $username) <br>{ <br>// 当验证通过后，启动 session <br>session_start(); <br>// 注册登陆成功的 admin 变量，并赋值 true <br>$_SESSION["admin"] = true; <br>} <br>else <br>{ <br>die("用户名密码错误"); <br>} <br>} <br>else <br>{ <br>die("用户名密码错误"); <br>} </pre><p>我们在需要用户验证的页面启动 session，判断是否登陆：</p><pre class="brush:php;">// 防止全局变量造成安全隐患 <br>$admin = false; <br>// 启动会话，这步必不可少 <br>session_start(); <br>// 判断是否登陆 <br>if (isset($_SESSION["admin"]) &amp;&amp; $_SESSION["admin"] == true) <br>{ <br>echo "您已经成功登陆"; <br>} <br>else <br>{ <br>// 验证失败，将 $_session["admin"] 置为 false <br>$_SESSION["admin"] = false; <br>die("您无权访问"); <br>} <br>?&gt; </pre><p>是不是很简单呢?将 $_session 看成是存储在服务器端的数组即可，我们注册的每一个变量都是数组的键，跟使用数组没有什么分别。</p><p>如果要登出系统怎么办?销毁 session 即可。</p><pre class="brush:php;">&lt;?php <br>session_start(); <br>// 这种方法是将原来注册的某个变量销毁 <br>unset($_SESSION["admin"]); <br>// 这种方法是销毁整个 session 文件 <br>session_destroy(); <br>?&gt; </pre><p>Session 能否像 Cookie 那样设置生存周期呢?有了 Session 是否就完全抛弃 Cookie 呢?我想说，结合 Cookie 来使用 session 才是最方便的。</p><p>Session 是如何来判断客户端用户的呢?它是通过 Session ID 来判断的，什么是 Session ID，就是那个 Session 文件的文件名，Session ID 是随机生成的，因此能保证唯一性和随机性，确保 Session 的安全。一般如果没有设置 Session 的生存周期，则 Session ID 存储在内存中，关闭浏览器后该 ID 自动注销，重新请求该页面后，重新注册一个 session ID。</p><p>如果客户端没有禁用 Cookie，则 Cookie 在启动 Session 会话的时候扮演的是存储 Session ID 和 session 生存期的角色。 我们来手动设置 session 的生存期：</p><pre class="brush:php;">session_start(); <br>// 保存一天 <br>$lifeTime = 24 * 3600; <br>setcookie(session_name(), session_id(), time() + $lifeTime, "/"); <br>?&gt; 　</pre><p>其实 Session 还提供了一个函数 session_set_cookie_params(); 来设置 Session 的生存期的，该函数必须在 session_start() 函数调用之前调用：</p><pre class="brush:php;">// 保存一天<br> &lt;?php <br>$lifeTime = 24 * 3600; <br>session_set_cookie_params($lifeTime); <br>session_start(); <br>$_session["admin"] = true; <br>?&gt; 　 </pre><p>如果客户端使用 IE 6.0 ， session_set_cookie_params(); 函数设置 Cookie 会有些问题，所以我们还是手动调用 setcookie 函数来创建 cookie。</p><p>假设客户端禁用 Cookie 怎么办?没办法，所有生存周期都是浏览器进程了，只要关闭浏览器，再次请求页面又得重新注册 Session。那么怎么传递 Session ID 呢?通过 URL 或者通过隐藏表单来传递，PHP 会自动将 session ID 发送到 URL 上，URL 形如：http://www.openphp .cn /index.php?PHPSESSID=bba5b2a240a77e5b44cfa01d49cf9669，其中 URL 中的参数 PHPSESSID 就是 Session ID了，我们可以使用 $_GET 来获取该值，从而实现 session ID 页面间传递。</p><pre class="brush:php;">// 保存一天 <br>&lt;?php <br>$lifeTime = 24 * 3600; <br>// 取得当前 session 名，默认为 PHPSESSID <br>$sessionName = session_name(); <br>// 取得 session ID $sessionID = $_GET[$sessionName]; <br>// 使用 session_id() 设置获得的 session ID <br>session_id($sessionID); <br>session_set_cookie_params($lifeTime); <br>session_start(); <br>$_session["admin"] = true; <br>?&gt; </pre><p>对于虚拟主机来说，如果所有用户的 Session 都保存在系统临时文件夹里，将给维护造成困难，而且降低了安全性，我们可以手动设置 Session 文件的保存路径，session_save_path()就提供了这样一个功能。我们可以将 session 存放目录指向一个不能通过 Web 方式访问的文件夹，当然，该文件夹必须具备可读写属性。</p><pre class="brush:php;">&lt;?php <br>// 设置一个存放目录 <br>$savePath = "./session_save_dir/"; <br>// 保存一天 <br>$lifeTime = 24 * 3600; <br>session_save_path($savePath); session_set_cookie_params($lifeTime); <br>session_start(); <br>$_session["admin"] = true; <br>?&gt; 　 </pre><p>同 session_set_cookie_params(); 函数一样，session_save_path() 函数也必须在 session_start() 函数调用之前调用。 我们还可以将数组，对象存储在 session 中。操作数组和操作一般变量没有什么区别，而保存对象的话，PHP 会自动对对象进行序列化(也叫串行化)，然后保存于 session 中。下面例子说明了这一点：</p><pre class="brush:php;">&lt;?php <br>class person <br>{ <br>var $age; <br>function output() <br>{ <br>echo $this-&gt;age; <br>} <br>function setAge($age) { <br>$this-&gt;age = $age; <br>} <br>} <br>?&gt; <br>setage.PHP <br>&lt;?php <br>session_start(); <br>require_once "person.PHP"; <br>$person = new person(); <br>$person-&gt;setAge(21); <br>$_session['person'] = $person; <br>echo "check here to output age"; <br>?&gt; <br>output.PHP <br>&lt;?php <br>// 设置回调函数，确保重新构建对象。 <br>ini_set('unserialize_callback_func', 'mycallback'); <br>function mycallback($classname) { <br>$classname . ".PHP"; <br>} <br>session_start(); <br>$person = $_session["person"]; <br>// 输出 21 <br>$person-&gt;output(); <br>?&gt; <br></pre><p>当我们执行 setage.php 文件的时候，调用了setage() 方法，设置了年龄为 21，并将该状态序列化后保存在 session 中(PHP 将自动完成这一转换)，当转到 output.php 后，要输出这个值，就必须反序列化刚才保存的对象，又因为在解序列化的时候需要实例化一个未定义类，所以我们定义了以后回调函数，自动包含 person.PHP 这个类文件，因此对象被重构，并取得当前 age 的值为 21，然后调用 output() 方法输出该值。</p>]]></description><category>PHP_Python</category><comments>http://camnpr.com/php-python/2249.html#comment</comments><wfw:comment>http://camnpr.com/</wfw:comment><wfw:commentRss>http://camnpr.com/feed.asp?cmt=2249</wfw:commentRss><trackback:ping>http://camnpr.com/cmd.asp?act=tb&amp;id=2249&amp;key=c47529e4</trackback:ping></item><item><title>怎么解决PHP无法实现多线程的问题</title><author>camnpr@163.com (佚名)</author><link>http://camnpr.com/php-python/2248.html</link><pubDate>Sat, 20 Feb 2016 10:31:49 +0800</pubDate><guid>http://camnpr.com/php-python/2248.html</guid><description><![CDATA[<p>有没有办法在PHP中实现多线程呢？假设你正在写一个基于多台服务器的PHP应用，理想的情况时同时向多台服务器发送请求，而不是一台接一台。可以实现吗？当有人想要实现并发功能时，他们通常会想到用fork或者spawn threads，但是当他们发现PHP不支持多线程的时候，大概会转换思路去用一些不够好的语言，比如Perl。<br />假设你要建立一个服务来检查正在运行的n台服务器，以确定他们还在正常运转。你可能会写下面这样的代码：</p><pre class="brush:php;">$hosts = array(&quot;host1.sample.com&quot;, &quot;host2.sample.com&quot;, &quot;host3.sample.com&quot;); <br />$timeout = 15; <br />$status = array(); <br />foreach ($hosts as $host) {  <br />    $errno = 0;  <br />    $errstr = &quot;&quot;;  <br />    $s = fsockopen($host, 80, $errno, $errstr, $timeout);  <br />    if ($s) {  <br />       $status[$host] = &quot;Connectedn&quot;;  <br />       fwrite($s, &quot;HEAD / HTTP/1.0rnHost: $hostrnrn&quot;);  <br />      do {   <br />        $data = fread($s, 8192);   <br />        if (strlen($data) == 0) {   <br />        break;   <br />        }   <br />       $status[$host] .= $data;  <br />     }  <br />     while (true);  <br />      fclose($s);  <br />     }  <br />     else {  <br />       $status[$host] = &quot;Connection failed: $errno $errstrn&quot;;  <br />     } <br />} <br />print_r($status); <br />?&gt;</pre><p>它运行的很好，但是在fsockopen()分析完hostname并且建立一个成功的连接（或者延时$timeout秒）之前，扩充这段代码来管理大量服务器将耗费很长时间。</p><p>因此我们必须放弃这段代码；我们可以建立异步连接-不需要等待fsockopen返回连接状态。PHP仍然需要解析hostname（所以直接使用ip更加明智），不过将在打开一个连接之后立刻返回，继而我们就可以连接下一台服务器。</p><p>有两种方法可以实现；PHP5中可以使用新增的stream_socket_client()函数直接替换掉fsocketopen()。PHP5之前的版本，你需要自己动手，用sockets扩展解决问题。下面是PHP5中的解决方法：</p><pre class="brush:php;">$hosts = array(&quot;host1.sample.com&quot;, &quot;host2.sample.com&quot;, &quot;host3.sample.com&quot;); <br />$timeout = 15; <br />$status = array(); <br />$sockets = array(); <br />/* Initiate connections to all the hosts simultaneously */ <br />foreach ($hosts as $id =&gt; $host) {  <br />    $s = stream_socket_client(&quot;$host:80&quot;, $errno, $errstr, $timeout,         STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);  <br />    if ($s) {  <br />      $sockets[$id] = $s;  <br />      $status[$id] = &quot;in progress&quot;;  <br />    }  <br />    else { $status[$id] = &quot;failed, $errno $errstr&quot;;  <br />    } <br />} <br />/* Now, wait for the results to come back in */ <br /> <br />while (count($sockets)) {  <br />   $read = $write = $sockets;  <br />/* This is the magic function - explained below */  <br />   $n = stream_select($read, $write, $e = null, $timeout);  <br />   if ($n &gt; 0) {  <br />   /* readable sockets either have data for us, or are failed  * connection attempts */  <br />     foreach ($read as $r) {    <br />          $id = array_search($r, $sockets);    <br />          $data = fread($r, 8192);    <br />     if (strlen($data) == 0) {   <br />          if ($status[$id] == &quot;in progress&quot;) {   <br />            $status[$id] = &quot;failed to connect&quot;;   <br />          }   <br />     fclose($r);   <br />     unset($sockets[$id]);    <br />      }  <br />      else {   <br />         $status[$id] .= $data;    <br />      }  <br />    }  <br />/* writeable sockets can accept an HTTP request */  <br />foreach ($write as $w) {   <br />     $id = array_search($w, $sockets);   <br />     fwrite($w, &quot;HEAD / HTTP/1.0rnHost: &quot;   <br />     . $hosts[$id] . &quot;rnrn&quot;);   <br />     $status[$id] = &quot;waiting for response&quot;;  <br />     }  <br />}  <br />else {  <br />/* timed out waiting; assume that all hosts associated  * with $sockets are faulty */  <br />foreach ($sockets as $id =&gt; $s) {   <br />     $status[$id] = &quot;timed out &quot;  <br />     . $status[$id];  <br />     }  <br />break;  <br /> } <br />} <br />foreach ($hosts as $id =&gt; $host) {  <br />   echo &quot;Host: $hostn&quot;; echo &quot;Status: &quot;  <br />   . $status[$id] . &quot;nn&quot;; <br />}  <br />?&gt; </pre><p>我们用stream_select()等待sockets打开的连接事件。stream_select()调用系统的select(2)函数来工 作：前面三个参数是你要使用的streams的数组；你可以对其读取，写入和获取异常（分别针对三个参数）。stream_select()可以通过设 置$timeout（秒）参数来等待事件发生-事件发生时，相应的sockets数据将写入你传入的参数。</p><p>下面是PHP4.1.0之后版本的实现，如果你已经在编译PHP时包含了sockets(ext/sockets)支持，你可以使用根上面类似的代 码，只是需要将上面的streams/filesystem函数的功能用ext/sockets函数实现。主要的不同在于我们用下面的函数代替 stream_socket_client()来建立连接：</p><pre class="brush:php;">// This value is correct for Linux, other systems have other values <br />define('EINPROGRESS', 115); <br />function non_blocking_connect($host, $port, &amp;$errno, &amp;$errstr, $timeout) {  <br />    $ip = gethostbyname($host);  <br />    $s = socket_create(AF_INET, SOCK_STREAM, 0);  <br />    if (socket_set_nonblock($s)) {  <br />      $r = @socket_connect($s, $ip, $port);  <br />      if ($r || socket_last_error() == EINPROGRESS) {   <br />         $errno = EINPROGRESS;   <br />         return $s;  <br />        }  <br />     }  <br />    $errno = socket_last_error($s);  <br />    $errstr = socket_strerror($errno);  <br />    socket_close($s);  <br />    return false; <br />} <br />?&gt; </pre><p>现在用socket_select()替换掉stream_select()，用socket_read()替换掉fread()，用socket_write()替换掉fwrite()，用socket_close()替换掉fclose()就可以执行脚本了！<br />PHP5的先进之处在于，你可以用stream_select()处理几乎所有的stream。例如你可以通过include STDIN用它接收键盘输入并保存进数组，你还可以接收通过proc_open()打开的管道中的数据。</p>]]></description><category>PHP_Python</category><comments>http://camnpr.com/php-python/2248.html#comment</comments><wfw:comment>http://camnpr.com/</wfw:comment><wfw:commentRss>http://camnpr.com/feed.asp?cmt=2248</wfw:commentRss><trackback:ping>http://camnpr.com/cmd.asp?act=tb&amp;id=2248&amp;key=5ceebef5</trackback:ping></item><item><title>汇总PHP中容易出错、混淆的知识点整理笔记</title><author>camnpr@163.com (佚名)</author><link>http://camnpr.com/php-python/2244.html</link><pubDate>Thu, 18 Feb 2016 10:23:46 +0800</pubDate><guid>http://camnpr.com/php-python/2244.html</guid><description><![CDATA[<p><strong>1.echo和print的区别</strong></p><p>PHP中echo和print的功能基本相同（输出），但是两者之间还是有细微差别的。echo输出后没有返回值，但print有返回值，当其执行失败时返回flase。因此可以作为一个普通函数来使用，例如执行下面的代码后变量$r的值将为1。</p><pre class="brush:php;">$r = print &quot;Hello World&quot;;  </pre><p>这意味着print可用在一些复杂的表达式中，而echo则不行。但是，因为echo语句不要求返回任何数值，所已在代码中echo语句的运行效率要略微快于print语句。</p><p><strong>2.include与require的区别</strong></p><p>include()与require()的功能也基本相同（包含），但在用法上也有一些不同，include()是有条件包含函数，而require()则是无条件包含函数。例如在下面代码中，如果变量$a为真，则将包含文件a.php：</p><pre class="brush:php;">if($a){   <br />include(&quot;a.php&quot;);   <br />}  </pre><p>而require()则和include()不同，不管$a取何值，下面的代码将把文件a.php包含进文件里：</p><pre class="brush:php;">if($a){   <br />require(&quot;a.php&quot;);   <br />} </pre><p>在错误处理方面，使用include语句，如果发生包含错误，程序将跳过include语句，虽然会显示错误信息但是程序还是会继续执行！但requre却会给你来个致命错误。</p><p>当然，从字面意思上我们也可以理解七分：requre是很强硬的请求、要求的意思。</p><p><strong>3.require_once()和include_once()语句</strong></p><p>题外话了，因为长的像，简单require_once()和include_once()语句分别对应于require()和include()语句。require_once() 和include_once()语句主要用于需要包含多个文件时，可以有效地避免把同一段代码包含进去而出现函数或变量重复定义的错误。</p><p><strong>4.空字符串('')和NULL的区别</strong></p><p>PHP中空字符串和NULL都是以值为0存储的，但是他们的类型并不一样，你可以试一下echo gettype('');和echo gettype(NULL);你会发现他们打印出来的分别是string和NULL，当然还有0也容易混淆，你可以试试echo gettype(0);打印一下类型，会发现0的类型是integer（整型），可见字符串('')、NULL和0是&ldquo;等值&rdquo;但不等类型。</p><p><strong>5.isset和 empty的区别</strong></p><p>从字面意思上我们就可以明白：empty是判断一个变量是否为&ldquo;空&rdquo;，而isset 则是判断一个变量是否已经设置。但是这里有一点绝对要注意起来：当一个变量值为0，empty 认为这个变量同等于空，即相当于没有设置。比如当我们检测＄id 变量的时候，当＄id=0 ，用empty和isset来检测变量＄id是否已经配置，两都将返回不同的值：empty 认为没有配置，isset 则能够取得 ＄id 的值，看下边例子：</p><pre class="brush:php;">$id=0;   <br />empty($id)?print &quot;我是空的&quot;:print &quot;我是$id .&quot;; //结果：我是空的   <br />!isset($id)?print &quot;我是空的&quot;:print &quot;我是$id .&quot;;//结果：我是0   <br /></pre><p><strong>6.==（等）和===（恒等）的区别</strong></p><p>回顾上面第四条空字符串(&quot;&quot;)和NULL的区别，再来看一个例子：</p><pre class="brush:php;">'' == NULL;   <br />'' === NULL;  </pre><p>运行之后你会发现第一个为true，而第二个则为false！可见==只是比较值是否相等，而===则不但比较值，还会比较类型，更为严格。</p><p><strong>7.self :: 和 this-&gt; 的区别</strong></p><p>在访问PHP类中的成员变量或方法时，如果被引用的变量或者方法被声明成const（定义常量）或者static（声明静态）,那么就必须使用操作符::,反之如果被引用的变量或者方法没有被声明成const或者static,那么就必须使用操作符-&gt;。</p><p>另外，如果从类的内部访问const或者static变量或者方法,那么就必须使用自引用的self，反之如果从类的内部访问不为const或者static变量或者方法,那么就必须使用自引用的$this。</p><p><strong>8.strstr() 与 strpos() 的区别</strong></p><p>stristr() 不区分大小写 strstr() 区分大小写</p><p>函数查找字符串在另一个字符串中第一次出现的位置。</p><p>如果成功，则返回字符串的其余部分（从匹配点）。如果没有找到该字符串，则返回 false。</p><p>stripos() 不区分大小写 strpos() 区分大小写</p><p>函数返回字符串在另一个字符串中第一次出现的位置。</p><p>如果没有找到该字符串，则返回 false。</p><p>经测试证明如果只是单纯查找判断是否存在则strpos()的执行效率要大于strstr()</p><p><strong>9.PHP中 HTTP_HOST 和 SERVER_NAME</strong></p><p><strong>相同点：</strong></p><p>当满足以下三个条件时，两者会输出相同信息。</p><p>1. 服务器为80端口</p><p>2. apache的conf中ServerName设置正确</p><p>3. HTTP/1.1协议规范</p><p><strong>不同点：</strong></p><p>1. 通常情况：</p><p>_SERVER[&quot;HTTP_HOST&quot;] 在HTTP/1.1协议规范下，会根据客户端的HTTP请求输出信息。</p><p>_SERVER[&quot;SERVER_NAME&quot;] 默认情况下直接输出apache的配置文件httpd.conf中的ServerName值。</p><p>2. 当服务器为非80端口时：</p><p>_SERVER[&quot;HTTP_HOST&quot;] 会输出端口号，例如：camnpr.com:8080</p><p>_SERVER[&quot;SERVER_NAME&quot;] 会直接输出ServerName值</p><p>因此在这种情况下，可以理解为：HTTP_HOST = SERVER_NAME : SERVER_PORT</p><p>3. 当配置文件httpd.conf中的ServerName与HTTP/1.0请求的域名不一致时：</p><p>httpd.conf配置如下：</p><p>ServerName camnpr.com</p><p>ServerAlias www.camnpr.com</p><p>客户端访问域名www.camnpr.com</p><p>_SERVER[&quot;HTTP_HOST&quot;] 输出 www.camnpr.com</p><p>_SERVER[&quot;SERVER_NAME&quot;] 输出 camnpr.com</p><p>所以，在实际程序中，应尽量使用_SERVER[&quot;HTTP_HOST&quot;] ，比较保险和可靠。</p><p>如果在端口映射的情况下，并且在内网访问，用&ldquo;$_SERVER['HTTP_X_FORWARDED_HOST']&rdquo;比较好。</p><p>经过小编对以上知识点的整理，大家的思路是不是更清晰了，对这些概念是不是有了区分，那就好好收藏这份笔记吧！</p>]]></description><category>PHP_Python</category><comments>http://camnpr.com/php-python/2244.html#comment</comments><wfw:comment>http://camnpr.com/</wfw:comment><wfw:commentRss>http://camnpr.com/feed.asp?cmt=2244</wfw:commentRss><trackback:ping>http://camnpr.com/cmd.asp?act=tb&amp;id=2244&amp;key=20d82e66</trackback:ping></item><item><title>PHP怎么直接修改表内容DataGrid功能实现代码</title><author>camnpr@163.com (佚名)</author><link>http://camnpr.com/php-python/2243.html</link><pubDate>Mon, 15 Feb 2016 10:31:30 +0800</pubDate><guid>http://camnpr.com/php-python/2243.html</guid><description><![CDATA[<div id="noimgcss"><p>由于需要连接Oracle所以从二次开发和页面样式来说个人觉得phpMyDataGrid还是比较好上手。<br /><strong>1. 创建测试数据库和表</strong></p><pre class="brush:sql;">create database `camnpr`; <br />  <br />USE `camnpr`;  <br />  <br />CREATE TABLE `employees` (  <br />   `id` int(6) NOT NULL auto_increment,  <br />   `name` char(20) default NULL,  <br />   `lastname` char(20) default NULL,  <br />   `salary` float default NULL,  <br />   `age` int(2) default NULL,  <br />   `afiliation` date default NULL,  <br />   `status` int(1) default NULL,  <br />   `active` tinyint(1) default NULL,  <br />   `workeddays` int(2) default NULL,  <br />   `photo` char(30) default NULL,  <br />   PRIMARY KEY (`id`)  <br />)  <br />  <br />insert into `employees`  <br />  (`id`,`name`,`lastname`,`salary`,`age`,`afiliation`,`status`,`active`,`workeddays`,`photo`)   <br />  values (1, 'Ana', 'Trujillo',2000,45, '2005-05-13',1,1,10, '1.jpg');  <br />insert into `employees`   <br />  (`id`,`name`,`lastname`,`salary`,`age`,`afiliation`,`status`,`active`,`workeddays`,`photo`)  <br />  values (2, 'Jennifer', 'Aniston',3500,23, '2004-10-22',1,0,0, '2.jpg');  <br />insert into `employees`   <br />  (`id`,`name`,`lastname`,`salary`,`age`,`afiliation`,`status`,`active`,`workeddays`,`photo`)  <br />  values (3, 'Michael', 'Norman',1200,19, '2007-01-10',1,1,5, '3.jpg');  <br />insert into `employees`   <br />  (`id`,`name`,`lastname`,`salary`,`age`,`afiliation`,`status`,`active`,`workeddays`,`photo`)  <br />  values (4, 'Vanessa', 'Black',6500,31, '2000-11-05',1,1,30, '4.jpg');  <br />insert into `employees`   <br />  (`id`,`name`,`lastname`,`salary`,`age`,`afiliation`,`status`,`active`,`workeddays`,`photo`)  <br />  values (5, 'Michael', 'Strauss',3200,45, '2006-10-21',2,0,22, '5.jpg');  <br />insert into `employees`   <br />  (`id`,`name`,`lastname`,`salary`,`age`,`afiliation`,`status`,`active`,`workeddays`,`photo`)  <br />  values (6, 'William', 'Brown',2300,21, '2001-03-10',3,1,10, '6.jpg');  <br />insert into `employees`   <br />  (`id`,`name`,`lastname`,`salary`,`age`,`afiliation`,`status`,`active`,`workeddays`,`photo`)  <br />  values (7, 'Lucca', 'Normany',2800,36, '2006-10-02',3,1,20, '7.jpg'); </pre><p><strong>2. PHP程序介绍</strong></p><p>phpMyDataGrid主要是通过phpmydatagrid.class.php，dgscripts.js来实现的，总共加起来不到100kB，又是一个小巧的软件。对于这两个文件就不多讲了，感兴趣的同学可以&ldquo;打包带走&rdquo;回去慢慢品。主要介绍该软件的使用方法，即实例 datagrid_for_mysql.php。先看一下页面示意图：</p><p style="text-align: center;" data-mce-style="text-align: center;"><img id="theimg" src="http://camnpr.com/upload/2016/1/201601281400257560.jpg" alt="PHP直接修改表内容DataGrid功能实现代码" /></p><p style="text-align: left;" data-mce-style="text-align: left;">程序讲解：</p><pre class="brush:php;">&lt;?php  <br />include (&quot;phpmydatagrid.class.php&quot;); <br />$objGrid = new datagrid; <br />$objGrid-&gt;closeTags(true);  <br />$objGrid-&gt;friendlyHTML();  <br />$objGrid-&gt;methodForm(&quot;get&quot;);  <br />//连接数据库 <br />$objGrid-&gt;conectadb(&quot;127.0.0.1&quot;, &quot;root&quot;, &quot;root&quot;, &quot;camnpr&quot;);//加密字符串 <br />$objGrid-&gt;salt(&quot;Myc0defor5tr0ng3r-Pro3EctiOn&quot;); <br />$objGrid-&gt;language(&quot;en&quot;); <br />//最后一列显示的功能键，从左向右功能为&ldquo;新增键&rdquo;、&ldquo;编辑键&rdquo;、&ldquo;删除键&rdquo;、&ldquo;浏览键&rdquo;。 <br />$objGrid-&gt;buttons(true,true,true,true); <br />//修改数值时产生的Form名称 <br />$objGrid-&gt;form('employee', true); <br />//可检索列名 <br />$objGrid-&gt;searchby(&quot;name,lastname&quot;); <br />//需要读取的表 <br />$objGrid-&gt;tabla(&quot;employees&quot;); <br />//索引值用于修改数据 <br />$objGrid-&gt;keyfield(&quot;id&quot;); <br />//分页显示行数 <br />$objGrid-&gt;datarows(20); <br />//默认排序方式 <br />$objGrid-&gt;orderby(&quot;name&quot;, &quot;ASC&quot;); <br />//显示列设置，相关设置可参考phpmydatagrid.class.php <br />$objGrid-&gt;FormatColumn(&quot;id&quot;, &quot;ID Employee&quot;, 5, 5, 1, &quot;50&quot;, &quot;center&quot;, &quot;integer&quot;); <br />$objGrid-&gt;FormatColumn(&quot;name&quot;, &quot;Name&quot;, 30, 30, 0, &quot;150&quot;, &quot;left&quot;); <br />$objGrid-&gt;FormatColumn(&quot;lastname&quot;, &quot;Last name&quot;, 30, 30, 0, &quot;150&quot;, &quot;left&quot;); <br />$objGrid-&gt;FormatColumn(&quot;age&quot;, &quot;Age&quot;, 5, 5, 0, &quot;50&quot;, &quot;right&quot;);//自定义日期格式 <br />$objGrid-&gt;FormatColumn(&quot;afiliation&quot;, &quot;Afiliation Date&quot;, 10, 10, 0, &quot;100&quot;, &quot;center&quot;, &quot;date:dmy:/&quot;);//编辑时可以自定义为&lt;Select&gt;模式 <br />$objGrid-&gt;FormatColumn(&quot;status&quot;, &quot;Status&quot;, 5, 5, 0, &quot;60&quot;, &quot;left&quot;, &quot;select:1_Single:2_Married:3_Divorced&quot;); <br />//编辑时可以自定义为&lt;CheckBox&gt;模式 <br />$objGrid-&gt;FormatColumn(&quot;active&quot;, &quot;Active&quot;, 2, 2, 0,&quot;50&quot;, &quot;center&quot;, &quot;check:No:Yes&quot;);//自定义货币显示形式 <br />$objGrid-&gt;FormatColumn(&quot;salary&quot;, &quot;Salary&quot;, 10, 10, 0, &quot;90&quot;, &quot;right&quot;, &quot;money:&euro;&quot;);//将数据以柱状图显示 <br />$objGrid-&gt;FormatColumn(&quot;workeddays&quot;, &quot;Work days&quot;, 5, 2, 0, &quot;50&quot;, &quot;right&quot;, &quot;chart:percent:val:31&quot;); <br />$objGrid-&gt;checkable(); <br />$objGrid-&gt;setHeader(); <br />$objGrid-&gt;ajax('silent'); <br />echo '&lt;html&gt; <br />   &lt;head&gt;&lt;title&gt;PHPDataGrid&lt;/title&gt;&lt;/head&gt; <br />   &lt;body&gt;&lt;div align=&quot;center&quot;&gt;&lt;br /&gt;'; <br />//生成DataGrid <br />$objGrid-&gt;grid(); <br />echo '&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;';//关闭数据库连接 <br />$objGrid-&gt;desconectar(); <br />?&gt; </pre><p><strong>3. 基于Oracle简介</strong></p><p>对于Oracle的读取主要是把phpmydatagrid.class.php中与MySQL连接的函数修改为Oracle，本篇是通过sqlrelay进行的Oracle连接，当然也可以使用PHP自带的OCI8模块（效率有些低），修改后另存为phporadatagrid.class.php即可在其他程序（datagrid_for_oracle.php）中调用。</p><p>以上就是教大家PHP如何直接修改表内容DataGrid功能的全过程，还有对数据库的了解，希望本文对大家的学习有所帮助。</p></div>]]></description><category>PHP_Python</category><comments>http://camnpr.com/php-python/2243.html#comment</comments><wfw:comment>http://camnpr.com/</wfw:comment><wfw:commentRss>http://camnpr.com/feed.asp?cmt=2243</wfw:commentRss><trackback:ping>http://camnpr.com/cmd.asp?act=tb&amp;id=2243&amp;key=70aa2703</trackback:ping></item><item><title>PHP怎么生成条形码的示例代码（带在线例子）</title><author>camnpr@163.com (佚名)</author><link>http://camnpr.com/php-python/2242.html</link><pubDate>Fri, 29 Jan 2016 10:42:20 +0800</pubDate><guid>http://camnpr.com/php-python/2242.html</guid><description><![CDATA[<div id="noimgcss"><p><span style="font-size: 13.2px;" data-mce-style="font-size: 13.2px;"><strong>先来感受一下条形码的生成和解读：</strong></span></p><ol>    <li><a href="http://camnpr.com/TuiJianTools/QR/index.aspx" target="_blank">在线生成二维码、条形码（带读取码图）</a></li></ol><p><span style="font-size: larger;" data-mce-style="font-size: larger;"><strong>1.什么是条形码？</strong></span></p><p>百度百科定义：条形码(barcode)是将宽度不等的多个黑条和空白，按照一定的编码规则排列，用以表达一组信息的图形标识符。常见的条形码是由反射率相差很大的黑条（简称条）和白条（简称空）排成平行线的图案。在日常生活中，条形码可以标出物品的生产国、制造厂家、商品名称、生产日期、图书分类号、邮件地点起止、类别、日期等许多信息。条形码编码格式具体请参考</p><p>打印出来的优惠券，商家需要用验证器读取条形码，来获得其有效性。</p><p><span style="font-size: larger;" data-mce-style="font-size: larger;"><strong>2.如何生成条形码？</strong></span></p><p>首先找到强大的开源资料，在barcode官网下载barcodegen.1d-php5.v5.0.1.zip版本，然后解压文件放到你的Apache服务器的根目录下</p><p><strong>2.1文件结构：</strong></p><p style="text-align: center;" data-mce-style="text-align: center;"><img id="theimg" src="http://camnpr.com/upload/2016/1/201601281053554832.jpg" alt="PHP生成条形码大揭秘" /></p><p><strong>2.2具体解析</strong></p><p>（1）class文件夹是已封装好生成条形码的类，只需要调用即可。</p><p>（2）index.php是一个可选择条件生成条形码的功能，是主程序的入口，而html文件夹是提供的被引用的代码，code39.php指的是指向默认的编码格式。</p><pre class="brush:php;">&lt;?php <br />header('Location: html/code39.php'); <br />?&gt; <br /></pre><p style="text-align: center;" data-mce-style="text-align: center;"><img id="theimg" src="http://camnpr.com/upload/2016/1/201601281052164184.jpg" alt="PHP生成条形码大揭秘" /></p><p>（3）test.php是另外一个例子，通过代码直接生成HELLO条形码。　</p><p style="text-align: center;" data-mce-style="text-align: center;"><img id="theimg" src="http://camnpr.com/upload/2016/1/201601281052171356.jpg" alt="PHP生成条形码大揭秘" /></p><pre class="brush:xhtml;">View Code  <br /> <br />&lt;?php <br />// 引用class文件夹对应的类 <br />require_once('class/BCGFontFile.php'); <br />require_once('class/BCGColor.php'); <br />require_once('class/BCGDrawing.php'); <br /> <br />// 条形码的编码格式 <br />require_once('class/BCGcode39.barcode.php'); <br /> <br />// 加载字体大小 <br />$font = new BCGFontFile('./class/font/Arial.ttf', 18); <br /> <br />//颜色条形码 <br />$color_black = new BCGColor(0, 0, 0); <br />$color_white = new BCGColor(255, 255, 255); <br /> <br />$drawException = null; <br />try { <br />  $code = new BCGcode39(); <br />  $code-&gt;setScale(2);  <br />  $code-&gt;setThickness(30); // 条形码的厚度 <br />  $code-&gt;setForegroundColor($color_black); // 条形码颜色 <br />  $code-&gt;setBackgroundColor($color_white); // 空白间隙颜色 <br />  $code-&gt;setFont($font); //  <br />  $code-&gt;parse('HELLO'); // 条形码需要的数据内容 <br />} catch(Exception $exception) { <br />  $drawException = $exception; <br />} <br /> <br />//根据以上条件绘制条形码 <br />$drawing = new BCGDrawing('', $color_white); <br />if($drawException) { <br />  $drawing-&gt;drawException($drawException); <br />} else { <br />  $drawing-&gt;setBarcode($code); <br />  $drawing-&gt;draw(); <br />} <br /> <br />// 生成PNG格式的图片 <br />header('Content-Type: image/png'); <br /> <br /> $drawing-&gt;finish(BCGDrawing::IMG_FORMAT_PNG); <br />?&gt;</pre><p><span style="font-size: larger;" data-mce-style="font-size: larger;"><strong>3.实际应用</strong></span></p><p>对于上面有个大概的了解后，下面我们可以重新整合下代码，更加方便的使用它。</p><p>首先新建buildcode.php文件中，根据test.php文件进行改写，从请求的文件中获取数据：</p><p><strong>1）.条形码的编码格式</strong></p><p><strong>2）.条形码需要的数据内容</strong></p><pre class="brush:php;">View Code  <br />&lt;?php <br />// Including all required classes <br />require_once('class/BCGFontFile.php'); <br />require_once('class/BCGColor.php'); <br />require_once('class/BCGDrawing.php');  <br />$codebar = $_REQUEST['codebar']; //条形码将要数据的内容  <br />// Including the barcode technology <br />require_once('class/'.$codebar.'.barcode.php');  <br />// Loading Font <br />$font = new BCGFontFile('./class/font/Arial.ttf', 12);  <br />// The arguments are R, G, B for color. <br />$color_black = new BCGColor(0, 0, 0); <br />$color_white = new BCGColor(255, 255, 255);  <br />$drawException = null; <br />try { <br />  $code = new $codebar();//实例化对应的编码格式 <br />  $code-&gt;setScale(2); // Resolution <br />  $code-&gt;setThickness(23); // Thickness <br />  $code-&gt;setForegroundColor($color_black); // Color of bars <br />  $code-&gt;setBackgroundColor($color_white); // Color of spaces <br />  $code-&gt;setFont($font); // Font (or 0) <br />  $text = $_REQUEST['text']; //条形码将要数据的内容 <br />  $code-&gt;parse($text); <br />} catch(Exception $exception) { <br />  $drawException = $exception; <br />}  <br />/* Here is the list of the arguments <br /> - Filename (empty : display on screen) <br /> - Background color */ <br />$drawing = new BCGDrawing('', $color_white); <br />if($drawException) { <br />  $drawing-&gt;drawException($drawException); <br />} else { <br />  $drawing-&gt;setBarcode($code); <br />  $drawing-&gt;draw(); <br />}  <br />// Header that says it is an image (remove it if you save the barcode to a file) <br />header('Content-Type: image/png');  <br />// Draw (or save) the image into PNG format. <br />$drawing-&gt;finish(BCGDrawing::IMG_FORMAT_PNG); <br />?&gt; <br /></pre><p>然后新建test.html文件，向buildcode.php请求数据</p><pre class="brush:xhtml;">&lt;!DOCTYPE html&gt; <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;Test with embedded image&lt;/title&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br /> &lt;img src=&quot;buildcode.php?codebar=BCGcode39&amp;text=abc123&quot;/&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; <br /></pre><p>最后进行访问，浏览器直接生成png格式的条形码</p><p style="text-align: center;" data-mce-style="text-align: center;"><img id="theimg" src="http://camnpr.com/upload/2016/1/201601281052174523.jpg" alt="PHP生成条形码大揭秘" /></p><p>其中codebar支持的编码格式可以由用户请求所得：</p><p><span style="background-color: #c0c0c0;" data-mce-style="background-color: #c0c0c0;">/*'BCGcodabar','BCGcode11','BCGcode39','BCGcode39extended','BCGcode93',　&nbsp; <br />'BCGcode128','BCGean8','BCGean13','BCGisbn','BCGi25','BCGs25','BCGmsi',　&nbsp; <br />'BCGupca','BCGupce','BCGupcext2','BCGupcext5','BCGpostnet','BCGothercode'*/　</span> <br />剩下的就是验证了</p><p><span style="font-size: larger;" data-mce-style="font-size: larger;"><strong>4.验证</strong></span></p><p>我们如何验证条形码是否有效，即能否读出条形码中的内容。</p><p>先将图片保存下来，然后访问官网提供的验证功能，将图片上传就Ok了！　</p><p style="text-align: center;" data-mce-style="text-align: center;"><img id="theimg" src="http://camnpr.com/upload/2016/1/201601281052178760.jpg" alt="PHP生成条形码大揭秘" /></p><p style="text-align: left;" data-mce-style="text-align: left;">今天和大家一起揭秘了php如何生成条形码的，希望大家可以对条形码的形成有个大概的了解，对今后的学习有所帮助。</p></div>]]></description><category>PHP_Python</category><comments>http://camnpr.com/php-python/2242.html#comment</comments><wfw:comment>http://camnpr.com/</wfw:comment><wfw:commentRss>http://camnpr.com/feed.asp?cmt=2242</wfw:commentRss><trackback:ping>http://camnpr.com/cmd.asp?act=tb&amp;id=2242&amp;key=35c1a71a</trackback:ping></item><item><title>分享php商品对比功能代码</title><author>camnpr@163.com (佚名)</author><link>http://camnpr.com/php-python/2241.html</link><pubDate>Thu, 28 Jan 2016 10:37:36 +0800</pubDate><guid>http://camnpr.com/php-python/2241.html</guid><description><![CDATA[<div id="noimgcss"><p>代码如下，欢迎探讨交流：</p><p style="text-align: center;" data-mce-style="text-align: center;"><img id="theimg" src="http://camnpr.com/upload/2016/1/201601281036328001.jpg" alt="php商品对比功能代码分享" ></p><p><strong>商品对比调用的JS文件（包含了商品对比框浮动JS）：</strong></p><pre class="brush:js;">/*浮动窗口*/ <br>(function(){   <br>  var n=10; <br>  var obj=document.getElementById("goods-compare"); <br>  if(!obj){ <br>    return false; <br>  } <br>  var x=0; <br>  window.onscroll=function(){ <br>    obj.style.top=(document.body.scrollTop||document.documentElement.scrollTop)+n+'px'; <br>  }; <br>  window.onresize=function(){ <br>    obj.style.top=(document.body.scrollTop||document.documentElement.scrollTop)+n+'px'; <br>  };   <br>})(); <br> //添加显示对比框 <br>function addcompare(chk){ <br>  $('#goods-compare').fadeIn().show(); <br>  var count=$(".compare-box li").length; <br>  if (count&gt;2)//这里可以修改对比的数据哦 <br>  { <br>    alert('产品比较最多选3种哦'); <br>    return; <br>  } <br> <br>  $.ajax({ <br>    type: 'post', <br>    url: 'ajax.php', <br>    data: { <br>      'action':'1', <br>      'gid':chk.gid,//商品ID <br>      'gname':chk.gname,//商品名称 <br>      'gtype':chk.gtype//商品类别，类别不同时不能比较 <br>    }, <br>    cache: false, <br>    async: false, <br>    success: function(result) { <br>      if(result!='') <br>      { <br>        alert(result); <br>      }else{ <br>        var url='http://www.camnpr.com/product-'+chk.gid+'.html';//设置商品的链接地址 <br>        $(".compare-box").append("&lt;li class='division clearfix' id='"+chk.gid+"'&gt;&lt;div class='span-3'&gt;&lt;a href='"+url+"' target='_blank' title='"+chk.gname+"'&gt;'"+chk.gname+"'&lt;/a&gt;&lt;/div&gt;&lt;span onclick=\"removecompare('"+chk.gid+"');\"&gt;删除&lt;/span&gt;&lt;/li&gt;") <br>        $("#comids").val($(".compare-box li").map(function(){//将对比的所有商品ID，赋值给#comids <br>          return $(this).attr('id'); <br>        }).get().join(",")); <br>      } <br>    } <br>  }); <br>} <br> <br>//删除对比产品 <br>function removecompare(id) <br>{ <br>  $.ajax({ <br>    type: 'post', <br>    url: 'ajax.php', <br>    data: { <br>      'action':'2', <br>      'gid':id <br>    }, <br>    cache: false, <br>    success: function(result) { <br>      $("#"+id).remove(); <br>      $("#comids").val($(".compare-box li").map(function(){ <br>        return $(this).attr('id'); <br>      }).get().join(",")); <br>    } <br>  }); <br>  <br>} <br>//清空对比产品 <br>function clearcompare() <br>{   <br>  $.ajax({ <br>    type: 'post', <br>    url: 'ajax.php', <br>    data: { <br>      'action':'3' <br>    }, <br>    cache: false, <br>    success: function(result) { <br>      $(".compare-box").html(''); <br>      $("#comids").val(''); <br>    } <br>  }); <br>} <br>//显示对比框 <br>function showcompare() <br>{ <br>  $.ajax({ <br>    type: 'post', <br>    url: 'ajax.php', <br>    data: { <br>      'action':'4' <br>    }, <br>    success: function(result) { <br>      if(result){ <br>        $(".compare-box").append(result); <br>        $("#comids").val($(".compare-box li").map(function(){ <br>          return $(this).attr('id'); <br>        }).get().join(",")); <br>        $('#goods-compare').fadeIn().show(); <br>      } <br>    } <br>  }); <br>  <br>} <br> <br>//点击关闭对比框 <br>$('.close-gc').click(function(){ <br>  $('#goods-compare').fadeOut().hide(); <br>}); <br></pre><p><strong>商品对比调用Ajax文件</strong></p><pre class="brush:php;">&lt;?php <br>function mb_unserialize($serial_str) { <br>  $serial_str =stripslashes($serial_str); <br>  return unserialize($serial_str); <br>} <br>if($_POST['action']=='1') {//add <br>  if(isset($_COOKIE['gtype'])) { <br>    if($_COOKIE['gtype']!=$_POST['gtype']) { <br>      echo '对不起，您选择的是不同类别的产品无法加入对比，请选择同类产品或清空当前对比栏再选择。'; <br>      return; <br>    } <br>  }else { <br>    setcookie('gtype',$_POST['gtype']); <br>  } <br>  if(isset($_COOKIE['gid'])) { <br>    $arr_str = $_COOKIE['gid']; <br>    $arr=mb_unserialize($arr_str); <br>    if(count($arr)&gt;2) {//商品比较数量 <br>      echo "商品比较最多选3种"; <br>      return; <br>    } <br>    foreach($arr as $val) { <br>      if($val[0]==$_POST['gid']) { <br>        echo "该商品已经加入对比框"; <br>        return; <br>      } <br>    } <br>    $info=array($_POST['gid'],$_POST['gname'],$_POST['gtype']); <br>    $arr[]=$info; <br>    $arr_str=serialize($arr); <br>    setcookie('gid',$arr_str); <br>  }else { <br>    $info=array($_POST['gid'],$_POST['gname'],$_POST['gtype']); <br>    $arr[]=$info; <br>    $arr_str=serialize($arr); <br>    setcookie('gid',$arr_str); <br>  } <br>}else if($_POST['action']=='2') {//delone <br>  $id=$_POST['gid']; <br>  $arr_str = $_COOKIE['gid']; <br>  $arr=mb_unserialize($arr_str);   <br>  foreach($arr as $key=&gt;$val) { <br>    if($val[0]==$id) { <br>      unset ($arr[$key]); <br>    } <br>  } <br>  $arr_str=serialize($arr);   <br>  setcookie('gid',$arr_str); <br>}else if($_POST['action']=='3') {//delall <br>  setcookie('gid',''); <br>  setcookie('gtype',''); <br>}else if($_POST['action']=='4') {//showlist <br>  if(isset($_COOKIE['gid'])) { <br>    $data=''; <br>    $arr_str = $_COOKIE['gid']; <br>    $arr=mb_unserialize($arr_str);  <br>    foreach ($arr as $val){      <br>      $url="http://www.camnpr.com/product-".$val[0].".html"; <br>      $data.="&lt;li id='{$val[0]}' class='division clearfix'&gt;&lt;div class='span-3'&gt;&lt;a href='{$url}' target='_blank' title='{$val[1]}'&gt;{$val[1]}&lt;/a&gt;&lt;/div&gt;&lt;span onclick=\"removecompare('{$val[0]}');\"&gt;删除&lt;/span&gt;&lt;/li&gt;"; <br>    } <br>    echo $data; <br>  }   <br>} <br>?&gt; </pre><p>以上就是商品对比功能实现代码，希望大家可以仔细研究，有好的想法大家一起探讨。</p></div>]]></description><category>PHP_Python</category><comments>http://camnpr.com/php-python/2241.html#comment</comments><wfw:comment>http://camnpr.com/</wfw:comment><wfw:commentRss>http://camnpr.com/feed.asp?cmt=2241</wfw:commentRss><trackback:ping>http://camnpr.com/cmd.asp?act=tb&amp;id=2241&amp;key=ee1221c3</trackback:ping></item></channel></rss>
