存档

文章标签 ‘案例’

shopex中集成的站长统计功能简单分析

2011年8月2日 1 条评论

shopex中集成了一键开启站长统计功能,而无需去CNZZ注册,在phpcms,phpwind等中也都有类似的功能,下面是对这个功能的简单分析,以后也可以偷偷用在自己的网站中,呵呵。

<?php
//我们的域名,这里可以不唯一的
$domain = 'localhost';
//这个应该是CNZZ授权给shopex的加密密钥,如果错了就不能快捷申请账号
$encodestr = 'A34dfwfF';
//这个就是CNZZ授权给shopex的快捷申请账号的URL地址
$url = 'http://wss.cnzz.com/user/companion/shopex.php?domain='.$domain.'&key='.md5($domain.$encodestr);
//获取网页内容得到这样的一个字符串 80772914@3780692425
$res = file_get_contents($url);
//左边是CNZZ统计的站点id,右边是密码
$res = explode('@',$res);
//登录到CNZZ统计的URL,把下面的地址复制到地址栏就可以看到效果了
//http://wss.cnzz.com/user/companion/shopex_login.php?site_id=80772914&password=3780692425
//会自动跳转到 http://wss.cnzz.com/v1/main.php?siteid=80772914&s=main_stat
$login = 'http://wss.cnzz.com/user/companion/shopex_login.php?site_id='.$res[0].'&password='.$res[1];
header("Location:$login");

php截取html字符串,并自动补全html代码

2011年6月18日 没有评论

实际开发中会经常碰到,很多人直接先strip_tags过滤掉html标签,但是就只剩下纯文本了,可读性非常差,下面是一个函数

/**
 * 截取HTML,并自动补全闭合
 * @param $html
 * @param $length
 * @param $end
 */
function subHtml($html,$length) {
 $result = '';
 $tagStack = array();
 $len = 0;

 $contents = preg_split("~(<[^>]+?>)~si",$html, -1,PREG_SPLIT_NO_EMPTY| PREG_SPLIT_DELIM_CAPTURE);
 foreach($contents as $tag)
 {
 if (trim($tag)=="")  continue;
 if(preg_match("~<([a-z0-9]+)[^/>]*?/>~si",$tag)){
 $result .= $tag;
 }else if(preg_match("~</([a-z0-9]+)[^/>]*?>~si",$tag,$match)){
 if($tagStack[count($tagStack)-1] == $match[1]){
 array_pop($tagStack);
 $result .= $tag;
 }
 }else if(preg_match("~<([a-z0-9]+)[^/>]*?>~si",$tag,$match)){
 array_push($tagStack,$match[1]);
 $result .= $tag;
 }else if(preg_match("~<!--.*?-->~si",$tag)){
 $result .= $tag;
 }else{
 if($len + mstrlen($tag) < $length){
 $result .= $tag;
 $len += mstrlen($tag);
 }else {
 $str = msubstr($tag,0,$length-$len+1);
 $result .= $str;
 break;
 }

 }
 }
 while(!empty($tagStack)){
 $result .= '</'.array_pop($tagStack).'>';
 }
 return  $result;
}

/**
 * 截取中文字符串
 * @param $string 字符串
 * @param $start 起始位
 * @param $length 长度
 * @param $charset  编码
 * @param $dot 附加字串
 */
function msubstr($string, $start, $length,$dot='',$charset = 'UTF-8') {
 $string = str_replace(array('&amp;', '&quot;', '&lt;', '&gt;','&nbsp;'), array('&', '"', '<', '>',' '), $string);
 if(strlen($string) <= $length) {
 return $string;
 }

 if(strtolower($charset) == 'utf-8') {
 $n = $tn = $noc = 0;
 while($n < strlen($string)) {
 $t = ord($string[$n]);
 if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
 $tn = 1; $n++;
 } elseif(194 <= $t && $t <= 223) {
 $tn = 2; $n += 2;
 } elseif(224 <= $t && $t <= 239) {
 $tn = 3; $n += 3;
 } elseif(240 <= $t && $t <= 247) {
 $tn = 4; $n += 4;
 } elseif(248 <= $t && $t <= 251) {
 $tn = 5; $n += 5;
 } elseif($t == 252 || $t == 253) {
 $tn = 6; $n += 6;
 } else {
 $n++;
 }
 $noc++;
 if($noc >= $length) {
 break;
 }
 }
 if($noc > $length) {
 $n -= $tn;
 }
 $strcut = substr($string, 0, $n);
 } else {
 for($i = 0; $i < $length; $i++) {
 $strcut .= ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i];
 }
 }

 return $strcut.$dot;
}

/**
 * 取得字符串的长度,包括中英文。
 */
function mstrlen($str,$charset = 'UTF-8'){
 if (function_exists('mb_substr')) {
 $length=mb_strlen($str,$charset);
 } elseif (function_exists('iconv_substr')) {
 $length=iconv_strlen($str,$charset);
 } else {
 preg_match_all("/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/", $text, $ar); 
 $length=count($ar[0]);
 }
 return $length;
}

巧用金山快盘搭建多地可用的SVN”服务器”

2011年5月5日 没有评论

这里说的SVN服务器,并不是一个真正的服务器,却具有svn服务器的功能。因为有些代码在家里和公司都需要维护,代码的同步变得有些麻烦,一开始用了google code,孰料google被狙,gogole account都登陆不上了,经过研究,发现了一个利用金山快盘搭建svn服务器的功能。

客户端用TortoiseSVN,其实TortoiseSVN不仅仅是个SVN客户端,还集成了一些svn服务器进行版本库管理的功能。在金山快盘里建立一个文件夹svn,在svn目录再建立一个空文件夹 project,在此文件夹上点右键,在弹出菜单中的TortoiseSvn下执行”在此创建版本库”命令。这样版本库就创建在了快盘上,以后版本库任意的改动,金山网盘都会帮我们自动同步到各台电脑上,当然前提是这些电脑都是开启了使用同一个账户的快盘。

版本库建好了,就相当于我们在每台有快盘的机器上都有个SVN服务器端,只是这里的版本库URL设置成版本库的位置 file:///X:/svn/project,这时就可以从TortoiseSVN里检出(checkout),提交(commit),和更新(update)了,这样我在公司修改了代码,提交以后,金山快盘会帮我把版本库文件同步到家里的电脑上,回到家里我只需要update一下,就可以看到在公司修改后的代码了。

顺便帮金山坐下广告,申请金山快盘的地址是:http://k.wps.cn/register/

php压缩/解压zip的利器-PclZip

2011年3月31日 没有评论

PclZip简介与使用

PclZip介绍
PclZip library能够压缩与解压缩Zip格式的压缩档(WinZip、PKZIP);且能对此类类档案进行处理,包括产生压缩档、列出压缩档的内容以及解压缩档案等等。由于能够在伺服器端进行压缩与解压缩的动作,所以相当方便使用。
PclZip定义一个PclZip类别,其类别物件可视为一个ZIP档案,亦提供method来进行处理。

如何使用PclZip
1.基础
所有的功能都由pclzip.lib.php这个档案提供,PclZip library可于其首页(www.phpconcept.net/pclzip/index.en.php)下载。所有的PKZIP档案其实就是一个PclZip的类别物件。当产生一个PclZip档案(ie, PclZip类别物件),就会先产生一个压缩档,且档名已经指定,但此压缩档的内容尚未存在:

< ?PHP
require_once('pclzip.lib.php');
$archive = new PclZip("archive.zip");
?>

此物件提供了一些public method可用来处理此档案。

2.参数
每一个method有其各自可使用的参数,包括有必须与非必须的参数:

< ?PHP
require_once('pclzip.lib.php');
$archive = new PclZip('archive.zip');

$v_list = $archive->add('dev/file.txt',
PCLZIP_OPT_REMOVE_PATH, 'dev');
?>

上例中的’dev/file.txt’就是必须参数;’PCLZIP_OPT_REMOVE_PATH’则为非必须参数。当然有些method也可以只包含非必须的参数:

< ?PHP
$list = $archive->extract(PCLZIP_OPT_PATH, "folder",
PCLZIP_OPT_REMOVE_PATH, "data",
PCLZIP_CB_PRE_EXTRACT, "callback_pre_extract",);
?>

上例中原本压缩档内档案存放的路径为/data,不过你可以指定解压缩至/folder中。此外,在解压缩之前,会呼叫callback function(’callback_pre_extract()’),此function可让使用者在解压缩的过程中变更档案存放路径与档名,或是选择某些档案不解压缩。
所有可用的非必要参数可参考网址(www.phpconcept.net/pclzip/man/en/index.php)。

3.回传值
每个method所回传的值可能会不同,将会在每个method中说明。不过大部分的method回传0、error或是阵列。

4.错误处理
从版本1.3之后,错误处理已经整合至PclZip类别中,当一个method回传错误码,可以得知一些额外的讯息以方便错误处理:
* errorName():回传错误名称
* errorCode():回传错误码
* errorInfo():回传错误的描述

接下来会举几个例子来说明如何使用PclZip。

PclZip实例1、产生ZIP压缩档
PclZip($zipname):为PclZip constructor,$zipname为PKZIP压缩档的档名。
主要是产生一个PclZip物件,即一个PKZIP压缩档;但此时,只有压缩档产生出来,并做一些检查(例如是否有开启zlib extension…等),除此之外,并没有做其他动作。
create($filelist, [optional arguments list]):将参数$filelist指定的档案或目录(包含当中所有档案与子目录)加入上述所产生的压缩档中。
而非必要的参数则能够修改压缩档内的档案存放路径。
此method可用的参数可以参考网志(www.phpconcept.net/pclzip/man/en/index.php)。

下面的示例说明如何产生PKZIP压缩档(档名为archive.zip),并将file.txt、data/text.txt以及目录folder(包含当中的档案与子目录)加入刚刚产生的archive.zip中:

< ?PHP
include_once('pclzip.lib.php');
$archive = new PclZip('archive.zip');
$v_list = $archive->create('file.txt,data/text.txt,folder');
if ($v_list == 0) {
die("Error : ".$archive->errorInfo(true));
}
?>

下面的示例说明基本上与上例一样产生archive.zip,但在将file.txt与text.txt压缩于其中时,将路径由data/改为install/ ;因此,在archive.zip中这两个档案的路径会是install/file.txt与install/text.txt

< ?PHP
include_once('pclzip.lib.php');
$archive = new PclZip('archive.zip');
$v_list = $archive->create('data/file.txt,data/text.txt',
PCLZIP_OPT_REMOVE_PATH, 'data',
PCLZIP_OPT_ADD_PATH, 'install');
if ($v_list == 0) {
die("Error : ".$archive->errorInfo(true));
}
?>

PclZip实例2、列出压缩档内容
listContent( ) :列出压缩档中的内容,包括档案的属性与目录:

< ?PHP
include_once('pclzip.lib.php');
$zip = new PclZip("test.zip");

if (($list = $zip->listContent()) == 0) {
die("Error : ".$zip->errorInfo(true));
}

for ($i=0; $i<sizeof ($list); $i++) {
for(reset($list[$i]); $key = key($list[$i]); next($list[$i])) {
echo "File $i / [$key] = ".$list[$i][$key]."<br>";
}
echo "<br />";
}
?></sizeof>

上例将会回传结果:
File 0 / [filename] = data/file1.txt
File 0 / [stored_filename] = data/file1.txt
File 0 / [size] = 53
File 0 / [compressed_size] = 36
File 0 / [mtime] = 1010440428
File 0 / [comment] =
File 0 / [folder] = 0
File 0 / [index] = 0
File 0 / [status] = ok

File 1 / [filename] = data/file2.txt
File 1 / [stored_filename] = data/file2.txt
File 1 / [size] = 54
File 1 / [compressed_size] = 53
File 1 / [mtime] = 1011197724
File 1 / [comment] =
File 1 / [folder] = 0
File 1 / [index] = 1
File 1 / [status] = ok

PclZip实例3、解压缩档案
extract([options list]) :解压缩PKZIP中的档案或目录。
[options list]可用的参数可参考网址(www.phpconcept.net/pclzip/man/en/index.php)。这些参数能让使用者在解压缩的时候有更多的选项,譬如指定变更解压缩档案的路径、指定只解压缩某些档案或不解压缩某些档案或者是将档案解压缩成字串输出(可用于readme档)。

下例是一个简单的解压缩档案示例,将压缩档archive.zip内的档案解压缩至目前的目录:

< ?PHP
require_once('pclzip.lib.php');
$archive = new PclZip('archive.zip');

if ($archive->extract() == 0) {
die("Error : ".$archive->errorInfo(true));
}
?>

下例是进阶的解压缩档案使用,archive.zip中所有档案都解压缩于data/中,而特别指明在install/release中的所有档案也直接丢于data/中,而非data/install/ release:

< ?PHP
include('pclzip.lib.php');
$archive = new PclZip('archive.zip');
if ($archive->extract(PCLZIP_OPT_PATH, 'data',
PCLZIP_OPT_REMOVE_PATH, 'install/release') == 0) {
die("Error : ".$archive->errorInfo(true));
}
?>

本文转自 http://www.ccvita.com/59.html

php 生成日历的简单程序

2011年2月18日 没有评论

<?php

$month = $_GET['m']?$_GET['m']:date(‘n’);
$year = $_GET['y']?$_GET['y']:date(‘Y’);

$start_week = date(‘w’,mktime(0,0,0,$month,1,$year));
$day_num = date(‘t’,mktime(0,0,0,$month,1,$year));
$end = false;
?>
<table>
<tr>
<td>星期日</td><td>星期一</td><td>星期二</td><td>星期三</td><td>星期四</td><td>星期五</td><td>星期六</td>
</tr>
<tr>
<?php
for($i = 0; $i<$start_week; $i++)
{
echo “<td></td>”;
}

$j=1;

while($j<=$day_num)
{
echo “<td>$j</td>”;
$week = ($start_week+$j-1)%7;

if($week ==6){
echo “\n\t</tr>\n”;
if($j != $day_num)
echo “\t<tr>\n\t\t”;
else $end = true;
}
$j++;
}
while($week%7 != 6)
{
echo “<td></td>”;
$week++;
}
if(!$end)
echo “\n</tr>”;
?>

</table>

分类: 全部文章, 学习笔记 标签: ,

javascript 表单 submit()错误

2010年10月18日 没有评论

做个简单的表单验证,调用表单对象的submit对象竟然出现submit is not a function这样的错误,花了半个晚上的时间,终于找出了原因

原来 js对submit关键字敏感,而我的表单中有按钮name=”submit”…

把所有的name=”submit”去掉一切正常

吐血。。。

纯javascript 单行向上滚动效果代码

2010年9月20日 没有评论
<style>
*{margin:0;padding:0;}
#scrollDiv {height:30px;overflow:hidden;position:relative;margin:50px;}
#scrollUl {position:absolute;}
#scrollUl li{height:30px;line-height:30px;}
</style>
<script type="text/javascript">
function scrollOneStep(obj)
{
var ul = document.getElementById(obj);
var li = ul.getElementsByTagName("li");
var li_move = li.item(0);
var line = 0 - parseInt(li_move.clientHeight);
var speed = 10;
var pix = 0;
t2 = setInterval(function(){
if(pix > line){
ul.style.top = ""+pix + "px";
pix --;
}else{
clearInterval(t2);
}
},speed);

ul.style.top += parseInt(ul.style.top)+30+"px";

ul.removeChild(li_move);
ul.appendChild(li_move);
ul.style.top = "0"

}

function scroll(obj)
{
var t= setInterval(function(){scrollOneStep(obj);},1000);
}
</script>
<div id="scrollDiv">
<ul id="scrollUl">
<li>164101***400</li>
<li>334205***400</li>
<li>164101***400</li>
<li>334205***400</li>
<li>164101***400</li>
<li>334205***400</li>
<li>164101***400</li>
</ul>
</div>
<script language="javascript"> scroll('scrollUl'); </script>

在php中使用 TCPDF 动态创建 PDF [转载]

2010年9月13日 没有评论

简介

TCPDF 是托管在 Sourceforge.net 上最活跃的项目之一,其完全在 PHP 上实现了强大的 PDF 生成引擎。这使得其更容易安装,即使在您无法访问系统目录或编译自己的代码的站点上。同时,通过让您直接查看 PHP 代码生成的结果,而不使用任何中间步骤,这使迭代开发更加容易。

TCPDF 支持一系列有用的图像格式,包括 SVG 矢量格式和位图格式,如 JPEG 和 PNG。一个简单独立的实用工具让您可以处理 TrueType、OpenType、PostScript Type 1 和 CID-0 字体,使它们可以添加到 TCPDF 创建的文档。您可以使用 TCPDF 来生成无数 1-D 和 2-D 条形码格式,且它支持所有常见的 PDF 功能,如书签、文档链接、压缩、注释、文档加密和数字签名。

用 PHP 编写 TCPDF 并使用其页面,这使其易于创建并部署 PDF 生成的 Web 页面。在您使用任何支持 Web 服务器和您最喜欢的 PHP 开发环境开发并部署 TCPDF 时,我将使用如下工具:

  • Eclipse V3.5.2 — 我最新欢的开源开发环境之一,其支持广泛的编程语言和环境。
  • PHP Development Tools V2.2.0 — 适用于 Eclipse 的 PHP 插件。
  • MAMP Pro V1.9 — 适用于 Mac OS X 的方便的程序包,其通过有用的 GUI 前端在一个隔离的环境中提供 Apache、MySQL 和 PHP。虽然 Mac OS X 附带安装 Apache 和 PHP,但我还是选择使用此工具,因为其提供了一系列稳定且容易分离的 Web 服务器/数据库/PHP。
  • TCPDF V5.0.006 — TCPDF 当前的稳定版本。

您可以在 参考资料 部分找到以上所有工具的下载链接。

如果您已经安装了 PHP,我们就来看看如何在您自己的网站上使用 TCPDF。我们将检查安装过程,然后我们将使用 PHP 生成一个显示可能来自任何电子商务站点的发票式样(invoice-style)文档的网页。此后,我们将使用 TCPDF 来创建一个使用类似格式的可打印的 PDF 版发票。


回页首

安装 TCPDF

当您从 Sourceforge.net 下载 TCPDF 时,它提供一个自包含的 ZIP 存档,也就是说,您可以使用您最喜欢的 ZIP 提取工具来解压存档,您最终将获得一个包含您所需要的所有信息的 TCPDF 目录。

如果您将 TCPDF 目录添加到您的 web 文档目录,则您可以通过加载 doc/index.html 访问 TCPDF 文档并通过加载 examples/index.php 文件查看任何示例,这也可在 TCPDF 网站上找到(请参考 参考资料)。

然而在您可以查看示例以前,您需要配置您的 TCPDF 安装。


回页首

配置 — 类 UNIX 系统

如果您正在类 UNIX® 系统上安装 TCPDF,则您需要更改文件模式,因为它们并没有全部被标记为可执行。在 Microsoft® Windows® 系统上存在一个创建 TCPDF 存档的副作用。幸运的是,很容易在来自 shell 的一个失衡中调整这些(请参考 清单 1)。您还需要确保缓存和图像目录是可写入的,因为 TCPDF 将在那里存储临时文件。

下一步,您需要将文件分配给用户和组 web 服务器;虽然这通常是用户 www 和组 www,但是这将取决于您的系统。如果您正在您的个人网站领域以外运行 TCPDF,(在您的主目录下通常是 public_html),则您可以跳过此步骤。
清单 1. 调整文件模式和所有权

$ cd tcpdf
$ find . -type f | xargs chmod -x
$ chmod +w cache images
$ chown -R www:www .

请注意命令可能使用 . 代替 : 来在一些系统上分离用户和组;如果出现问题,则检查其文档详细资料。


回页首

适用于每个人的配置

使用您最喜欢的文本编辑器,加载 config/tcpdf_config.php 文件。这就是 TCPDF 的配置设置并让您控制库的默认设置,并告诉它如何找到自己的支持文件。

在 tcpdf_config.php 中您想要变更的设置包括:

  • PDF_PAGE_FORMAT — 如果您不使用公制页面格式,则设置其为 letter。除非您手头有一些非常奇特方法,否则 TCPDF 可能比您的打印机支持更大的页面尺寸。
  • PDF_UNIT — 如果您想用点而不是毫米来布置您的 PDF 文档,则设置其为 pt
  • PDF_CREATORPDF_AUTHOR — 一旦您的 PDF 生成代码忘了设置它们,则默认文档创建者和作者。

您可以在您的 PHP 代码中调整这些设置中的任意一个,如果无法确定也无需担心(例如,如果您在此处设置的是像模式文档布局,您仍然可以创建景观文档)。

假设您没有移动文件和目录远离其初始位置,则通过默认配置设置,TCPDF 应该没有呈现任何其附带示例的问题。

在这一点上,您可以加载示例文件以确保您拥有一个正在运行的 TCPDF 安装。让我们使用它来创建一个可打印版的发票。


回页首

创建发票

在您创建了电子商务网站以后,您的客户将订购一些物品,而您将收取他们的货款。虽然这很不错,但是他们将想得到某种发票,以防订单错误或他们的信用卡公司搞混了付款,。

让我们制作一个合理美观的发票网页,这样他们可以看到他们已经订购了什么和您将要向他们收取什么。


回页首

第一个版本 — Web 页面

使用我最喜欢的 PHP 开发环境,我已经创建了一个新的发票文件夹,其包含如下文件:

  • Invoice.php — PHP 生成发票
  • Invoice.css — CSS 式样的发票
  • Azuresol_OnyxTree-S.png — Azuresol 的 “OnyxTree S”,您将其用作您公司的标志(来自 iconfinder.com Web 站点的免费图标(请参考 参考资料))
  • gentleface_print.png — gentleface 的 “Print”,您将使用其触发 PDF 生成(来自 iconfinder.com 的另一个免费图标)

在 Invoice.php 内部,检查看看是否使用 PDF 参数调用页面(请参考 清单 2)。如果不是,用户想要一个正常 web 页面,这样您就可以使用 generateHTML 函数(请参考 清单 3)显示页面。稍后您将看到 generatePDF 函数,但是可以肯定使用它来生成发票数据的 PDF 没任何问题。
Listing 2. 页面生成控制代码

if( array_key_exists( 'PDF', $_REQUEST ) ) {
    generatePDF( $invoiceData );
} else {
    generateHTML( $invoiceData );
}

$invoiceData 阵列拥有所有发票数据;虽然您将直接在 Invoice.php 上创建它,但是您可以设想数据来自于数据库、web 服务或某种网上购物车系统。
清单 3. 生成 HTML

function generateHTML( $data ) {
?>
... HTML code was here ...
<?php
    foreach( $data['items'] as $item ) {
        echo '<tr>' . "\n";
        echo '    <td>' . $item[0] . "</td>\n";
        echo '    <td>' . $item[1] . "</td>\n";
        echo '    <td>' . $item[2] . "</td>\n";
        echo '    <td>' . $item[3]. "</td>\n";
        echo "</tr>\n";
    }
?>
... HTML code was here ...
<?php
    echo '<td>' . $data['total'] . "</td>\n";
?>
... HTML code was here ...
<?php
    echo 'Invoice prepared for ' . $data['user'] . ' on ' . $data['date'] . "\n";
?>
... HTML code was here ...
<?php

}

为了简单明了我已经删掉了此处所有的 HTML 标记代码;您可以在位于 CreatingPDFs-Invoice.zip 存档文件中的 Invoice.php 上看到它, CreatingPDFs-Invoice.zip 存档文件可以在 下载 部分找到。

使用传递给函数的发票信息作为 $data,创建一个包含每个项目一行的表、及其数量、单价和总价的表。在表的末尾,添加一个包含订单的总成本的行。页脚包含用户 ID 和发票生成的日期/时间。

当然,简单明了的事情,以及您在自己站点上实现它的时候所面临的主要挑战,将与您的数据源互动,并获得恰到好处的 CSS 式样。
图 1. 光彩夺目的网页发票
截图显示了一个有吸引力的可打印发票示例;Sumatra Special 的最大数量为 24,而其他的则处于 1 到 5 之间

我完全虚构了一家提供优良咖啡和茶的 South Seas Pacifica 公司,显然我对 Sumatran 品种深深的吸引了。至少他们的价格很吸引人!

右下角的打印机图标是诱人的,您希望能够有单击那里并获得打印发票。这里就是 TCPDF 的用武之地。并不只是打印网页,您将为我们尊贵的客户提供一个时髦的 PDF 版本,这会使他们在轻松的状态下完成打印。


回页首

第二个版本 — PDF

现在,您的网页发票看起来很好,您需要创建可以打印的 PDF 版本。

回忆 清单 2,将 PDF 参数 (http://…/Invoice.php?PDF) 与 Invoice.php 页面一起加载将调用具有相同数据的 generatePDF 函数(请参考清单 4)。
清单 4. 生成 PDF 发票

function generatePDF( $data ) {
    # Create a new PDF document.
    $pdf = new InvoicePdf( $data, 'P', 'pt', 'LETTER' );

    # Generate the invoice.
    $pdf->CreateInvoice();

    # Output the PDF document.
    $pdf->Output( 'Your_Invoice.pdf', 'D' );
}

generatePDF 函数创建了一个 InvoicePdf 对象,调用其 CreateInvoice 方法,然后发送一个名为 Your_Invoice.pdf 的下载 PDF 文档给用户的浏览器。虽然这看起来非常简单,但是隐藏了必须自己创建 InvoicePdf 类的事实,且需要复制原始发票式样。让我们来看看这是如何进行的。

InvoicePdf 类扩展了 TCPDF 的 TCPDF 类,这是主 PDF 生成引擎。在构造函数(请参考 清单 5)中,使用传入的 $orientation(页面方向)、$unit(计量单位)和 $format(页 面大小)初始化父类。TCPDF 构造函数的最后三个参数表明输入的是 Unicode(默认为 Ture),已生成 PDF 的字符编码格式是 UTF-8,且您不应使用磁盘缓存 (False)。虽然在创建 PDF 时,磁盘缓存减少了内存占用,但是速度变得更慢了。因为我们的文件不大也不复杂,所以无需权衡这一点。

在初始化父类以后,将参考存储到发票数据以便今后使用。下一步,使用 SetMargins 方法将页边距设置为宽度 72 点、高度 36 点。SetMargins 最终参数表明您正在用自己的值来重写默认页边距。使用 SetAutoPageBreaks 方法,可在从底部算起有 36 点高时告知 TCPDF 自动创建新页面。
清单 5. InvoicePdf 类构造函数

function __construct( $data, $orientation, $unit, $format ) {
    parent::__construct( $orientation, $unit, $format, true, 'UTF-8', false );

    $this->invoiceData = $data;

    # Set the page margins: 72pt on each side, 36pt on top/bottom.
    $this->SetMargins( 72, 36, 72, true );
    $this->SetAutoPageBreak( true, 36 );

    # Set document meta-information
    $this->SetCreator( PDF_CREATOR );
    $this->SetAuthor( 'Chris Herborth (chrish@pobox.com)' );
    $this->SetTitle( 'Invoice for ' . $this->invoiceData['user'] );
    $this->SetSubject( "A simple invoice example for 'Creating PDFs on
the fly with TCPDF' on IBM's developerWorks" );
    $this->SetKeywords( 'PHP, sample, invoice, PDF, TCPDF' );

    //set image scale factor
    $this->setImageScale(PDF_IMAGE_SCALE_RATIO); 

    //set some language-dependent strings
    global $l;
    $this->setLanguageArray($l);
}

在建立边距以后,设置 PDF 文档元信息。这将显示在您最喜欢的 PDF 查看器中的文档属性窗口。这些仅仅是字符串,因此您可以将它们设置为任何对您的应用程序有意义的信息。

使用 setImageScale 方法,在 TCPDF 的配置文件中使用默认图像缩放比例设置。这是用于将位图图像的大小从像素大小调整为适合的页面。

最后,使用 setLanguageArray 来为 PDF 文件设置一些语言相关的字符串;通过 TCPDF 主配置,这些会在特定语言配置文件中定义。

清单 6 中,您重写了 Header 方法,其被调用以便生成每一个页面的标题内容。首先,定义一些变量。以 14 点的 bigFont 大小开始,您会计算出商标图像的相对大小和相对于 bigFont 大小的正常文本大小。然后您将深入 TCPDF 调用。

ImagePngAlpha 方法插入放置在其左上角宽 72 点、高 32 点的商标图像,其与您以前的边距设置相匹配。因为它是一个正方形的图像,所以您可以指定相同的宽度和高度(已计算的 $imageScale)。您将要说明它是一个 PNG 图像,因为此调用实际可以插入 PNG 和 JPEG 图像(如果在您的 PHP 安装中已安装了 GD 库,则其也可以加载任何由 GD 支持的图像)。下一步,指定一个空值,因为您没有为此图像添加 PDF 链接(通过 AddLink 方法创建)目标。再下一步,使用 T 来说明您想在图像区域的右上角制定下一个 PDF 对象。最后,告知 TCPDF 不要调整图像大小,既保持初始的 72 dpi(一个通用的屏幕分辨率),且图像在页面上应该左对齐。

显然,ImagePngAlpha 方法对如何在 PDF 文档中将图像添加到页面的问题上给予您大量的控制(请参考清单 6)。
清单 6. 页面标题的生成

public function Header() {
    global $webcolor;

    # The image is this much larger than the company name text.
    $bigFont = 14;
    $imageScale = ( 128.0 / 26.0 ) * $bigFont;
    $smallFont = ( 16.0 / 26.0 ) * $bigFont;

    $this->ImagePngAlpha('Azuresol_OnyxTree-S.png', 72, 36, $imageScale,
$imageScale, 'PNG', null, 'T', false, 72, 'L' );
    $this->SetFont('times', 'b', $bigFont );
    $this->Cell( 0, 0, 'South Seas Pacifica', 0, 1 );
    $this->SetFont('times', 'i', $smallFont );
    $this->Cell( $imageScale );
    $this->Cell( 0, 0, '', 0, 1 );
    $this->Cell( $imageScale );
    $this->Cell( 0, 0, '31337 Docks Avenue,', 0, 1 );
    $this->Cell( $imageScale );
    $this->Cell( 0, 0, 'Toronto, Ontario', 0, 1 );

    $this->SetY( 1.5 * 72, true );
    $this->SetLineStyle( array( 'width' => 2, 'color' =>
array( $webcolor['black'] ) ) );
    $this->Line( 72, 36 + $imageScale, $this->getPageWidth() - 72, 36
+ $imageScale );
}

在标题上放置商标图像以后,设置字体(粗体 Times,使用您的 bigFont 大小),然后创建一些单元格来存放公司的名称和地址信息。这些单元格在 HTML 上包含文本,而且有点像表格单元格。Cell 方法采用这些参数(实际上更多;参考 TCPDF 文档获取完整列表):

  • Width — 单元格宽度;如果设置为 0,则单元格一直扩展到右侧边距(或者如果您使用的是从右到左的语言,则扩展到左侧边距)。
  • Height — 单元格高度;如果设置为 0,则单元格高度将扩展,以便能放得下内容。
  • Text — 该文本在单元格内绘制,使用当前的字体和颜色设置。
  • Border — 说明是否边界应该根据单元格制定。在这种情况下,由于您正在使用 0,所以您无需任何边界。您也可以传递 1 来根据单元格制定完整的边界,或字符串以便说明特定的边界。
  • Position — 说明何处创建下一个单元格;1 表明您需要其在下一行的开始出显示,但是您可以使用 0 在此单元格旁边添加下一个单元格,或者 2 以停留在当前的 X 坐标并移到下一行。

最后,我们的 Header 方法在标题的底部绘制了一条两点黑线,一直穿过页面的内容区域。图 2 显示了将如何在页面上查看,如 Mac OS X 的 预览应用程序所呈现的那样。
图 2. 打印标题,就像网页标题
截图对左边的地址显示了带有图形商标的标题,名称使用大的、粗体的字体,且地址使用斜体

现在您已经创建了一个原始标题的合理副本,您也需要重写 Footer 方法,以便于您生成页脚。这非常简单,只包含用户 ID 和发票信息,其通过另外一个两点黑线从剩余的页面中分离出来。

您尚未看到此方法的唯一部分正在使用使用一个负值调用 SetY 方法。在您这样做的时候,相对于页面的底部设置当前的 Y。在这里,您将要为页面页脚留下大量的空间,以确保您的绘制不太接近底部边距(请参考清单 7)。
清单 7. 页面页脚的生成

public function Footer() {
    global $webcolor;

    $this->SetLineStyle( array( 'width' => 2, 'color' =>
array( $webcolor['black'] ) ) );
    $this->Line( 72, $this->getPageHeight() - 1.5 * 72 - 2,
$this->getPageWidth() - 72, $this->getPageHeight() - 1.5 * 72 - 2 );
    $this->SetFont( 'times', '', 8 );
    $this->SetY( -1.5 * 72, true );
    $this->Cell( 72, 0, 'Invoice prepared for ' .
$this->invoiceData['user'] . ' on ' . $this->invoiceData['date'] );
}

在您创建页面时,显示出来的就像发票的网络版,只是减去了打印机的图标。您已经中断了此操作,因为这是打印版本(它是多余的)。图 3 得出了结果。
图 3. 已打印的页脚
截图显示了页脚,其对带有收件人、时间和日期的详细信息用粗体水平线标出

在这一点上,您拥有附带美观的页眉和页脚的空白页。您需要为此添加实际的发票内容,这样做很有用。

在使用 AddPage 方法启动新的页面以后(在这种情况下,这是唯一的页面),将字体设置为 11 点 Helvetica 并将插入点从页面的顶部移动到 144 点处。在表开始以前,这会在页眉以下给我们留出一个小空间。

下一步,要计算您将需要使表居中的缩进量,这基于页面宽度、两个 72 点边距、一个宽列和三个正常列。

在此之后,您将使用以前计算出的值并描绘出每个单元格的完全边界,来创建一系列单元格以呈现列标题。您还要右对齐数字列的标题因为它们通过值进行排列。在标题单元格的最后,您要调用 Ln 方法以便向下移动到下一行的开始。

通过在发票上迭代项目的 foreach 循环,您为每一个内容行进行同类型的布局(请参考清单 8)。
清单 8. 页面内容的生成

public function CreateInvoice() {
    $this->AddPage();
    $this->SetFont( 'helvetica', '', 11 );
    $this->SetY( 144, true );

    # Table parameters
    #
    # Column size, wide (description) column, table indent, row height.
    $col = 72;
    $wideCol = 3 * $col;
    $indent = ( $this->getPageWidth() - 2 * 72 - $wideCol - 3 * $col ) / 2;
    $line = 18;

    # Table header
    $this->SetFont( '', 'b' );
    $this->Cell( $indent );
    $this->Cell( $wideCol, $line, 'Item', 1, 0, 'L' );
    $this->Cell( $col, $line, 'Quantity', 1, 0, 'R' );
    $this->Cell( $col, $line, 'Price', 1, 0, 'R' );
    $this->Cell( $col, $line, 'Cost', 1, 0, 'R' );
    $this->Ln();

    # Table content rows
    $this->SetFont( '', '' );
    foreach( $this->invoiceData['items'] as $item ) {
        $this->Cell( $indent );
        $this->Cell( $wideCol, $line, $item[0], 1, 0, 'L' );
        $this->Cell( $col, $line, $item[1], 1, 0, 'R' );
        $this->Cell( $col, $line, $item[2], 1, 0, 'R' );
        $this->Cell( $col, $line, $item[3], 1, 0, 'R' );
        $this->Ln();
    }

    # Table Total row
    $this->SetFont( '', 'b' );
    $this->Cell( $indent );
    $this->Cell( $wideCol + $col * 2, $line, 'Total:', 1, 0, 'R' );
    $this->SetFont( '', '' );
    $this->Cell( $col, $line, $this->invoiceData['total'], 1, 0, 'R' );
}

代码的最后一位呈现总行数。这演示了您如何可以更容易地在单元格之间变更字体式样(通过调用 SetFont 方法来打开或关闭粗体)。第一个文本单元格的宽度被设置横跨表的前三列,因为您需要发票总数出现在最后一列的底部。

一旦您完成后,发票项目表看起来将非常的棒(请参考图 4)。
图 4. 发票上的项目
附带数量、价格和总数的项目格式化清单的截图

通过逻辑地布局文本单元格,您已经用适合打印的格式重新创建了初始的网页。在无需变更网页本身或任何基础数据的情况下,TCPDF 让您将创建 PDF 的支持添加到您现存的 PHP 网页上。


回页首

结束语

本文向您介绍了 TCPDF,它是一种用于生成 PDF 文档的流行 PHP 库。TCPDF 无需额外的库就能执行此操作,并使其作为您现有 PHP 网站的一部分易于安装。本文向您显示了在类 UNIX 系统中安装并配置 TCPDF 的概述。然后您创建了一个简单的基于 Web 的发票,类似于您可能在一家从事异国热饮的电子商务站点上所看到的诸如此类的事情。

一旦您拥有一个看上去像专业发票的网页,您就可以扩展 TCPDF 类来生产一个 PDF 版本的发票,即客户可以轻松地下载或打印。重写 HeaderFooter 方法让我们用相似的方式建立页面,然后您可以编写一个附加方法来布置发票项目作为一个表。


回页首

下载

描述 名字 大小 下载方法
文章源代码 os-tcpdf-CreatingPDFs-Invoice.zip 21KB HTTP

关于下载方法的信息

本文转载自IBM.COM

http://www.ibm.com/developerworks/cn/opensource/os-tcpdf/index.html?ca=drs-

php采集类

2009年10月29日 没有评论

一个自己写的php采集类,充分利用正则的强大字串处理能力,使用简单,功能也比较简单,能满足一般应用,功能也在不断完善中,使用过程:设置一个初始url,添加导航规则,添加采集字段和规则,保存输出即可

使用代码如下

$spider  = new spider();
$spider->addStartUrl(‘http://www.onlinedown.net/hits/week_{2,3}.htm’);
$spider->addLayer(0,’list’,’../soft/{*}.htm’);
$spider->addField(‘title’,'<title>{title}</title>’,array(‘华军软件园’,'安风信息网’));
$spider->run();
$spider->output();

上面采集的是华军软件的一周软件排行
源码如下

set_time_limit(0);
header("Content-type: text/html; charset=utf-8");
/**
* 采集程序类
* @author shooting
* @version 1.0.0
*/
class spider
{

/**
* 采集的终端页地址
*
* @var array
*/
var $pages = array();
/**
* 采集结果
*
* @var array
*/
var $result = array();
/**
* 第一层链接页面
*
* @var array
*/
var $startUrls = array();
/**
* 超时时间
*
* @var integer
*/
var $timeout;
/**
* 正在处理的文件内容
*
* @var string
*/
var $httpContent;
/**
* 正在处理的文件头
*
* @var array
*/
var $httpHead=array();
/**
* 自定义的head数组
*
* @var array
*/
var $putHead = array();
/**
* 采集字段与规则数组
*
* @var array
*/
var $field_arr = array();
/**
* 采集层次数
*
* @var interger
*/
var $deep;
/**
* 采集层次结构
*
* @var array
*/
var $layout_arr = array();
/**
* 采集限制条数
*
* @var integer
*/
var $limit = 0;

/**
* 程序运行时间
*
* @var float
*/
var $runtime = 0;

/**
* 被采集页面编码
*
* @var string
*/
var $charset = 'UTF-8';
/**
* 页面引用地址
*
* @var string
*/
var $httpreferer;

var $pagelimit = 0;

var $filepath = './';

function spider()
{
$this->timeout = 30;
}
/**
* 运行采集
*
* @return array
*/
function run()
{
$begintime = $this->microtime_float();
$cnt = 1;
foreach ($this->startUrls as $starturl){
/**
* 解析出起始地址中的页码区间
*/
if(preg_match(“~\{(\d+),(\d+)\}~”,$starturl,$pagenum)){
$pagebegin = intval($pagenum[1]);
$pageend = intval($pagenum[2]);
for(;$pagebegin<=$pageend;$pagebegin++){
$starturl = str_replace($pagenum[0],$pagebegin,$starturl);
$urllists = $this->getLists($this->layout_arr[0]['pattern'],$this->getContent($starturl));
foreach ($urllists as $url){
if(($this->limit > 0 && $cnt <= $this->limit)||$this->limit == 0)
{
$this->filterContent($this->getContent($url,$starturl));
$cnt++;
}
}
}
}else{
$urllists = $this->getLists($this->layout_arr[0]['pattern'],$this->getContent($starturl));
foreach ($urllists as $url){
if(($this->limit > 0 && $cnt <= $this->limit)||$this->limit == 0)
{
$this->filterContent($this->getContent($url,$starturl));
$cnt++;
}
}
}
}
$this->runtime = $this->microtime_float()-$begintime;
return $this->result;
}

/**
* 从文字段中根据规则提取出url列表
*
* @param string $pattern
* @param string $content
* @return Array
*/
function getLists($pattern=”,$content=”)
{
if(strpos($pattern,’{*}’) === false)return array($pattern);
$pattern = preg_quote($pattern);
$pattern = str_replace(‘\{\*\}’,'([^\'\">]*)’,$pattern);
$pattern = “~”.$pattern.”~is”;
preg_match_all($pattern,$content,$preg_rs);
return array_unique($preg_rs[0]);
}

/**
* 获取指定url的html内容包括头
*
* @param string $url
* @return string
*/
function getContent($url,$referer = ”)
{
$url = $this->urlRtoA($url,$referer);
preg_match(“/(http:\/\/)([^:\/]*):?(\d*)(\/?.*)/i”,$url,$preg_rs);
$host = $preg_rs[2];
$port = empty($preg_rs[3])?80:$preg_rs[3];
$innerUrl = $preg_rs[4];

$fsp = fsockopen($host,$port,$errno,$errstr,$this->timeout);
if(!$fsp)$this->log($errstr.’(‘.$errno.’)');
$output = “GET $url HTTP/1.0\r\nHost: $host\r\n”;
if(!isset($this->putHead['Accept']))$this->putHead['Accept']= “*/*”;
if(!isset($this->putHead['User-Agent']))$this->putHead['User-Agent']=’Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2)’;
if(!isset($this->putHead['Refer'])){
$this->putHead['Refer'] = ($referer == ”)?’http://’.$host:$referer;
}
foreach ($this->putHead as $headname => $headvalue){
$output .= trim($headname).’: ‘.trim($headvalue).”\r\n”;
}

$output .= “Connection: close\r\n\r\n”;
fwrite($fsp,$output);

$content = ”;
while (!feof($fsp)) {
$content .= fgets($fsp,256);
}
fclose($fsp);

$this->getHead($content);
$this->httpContent = $content;
if(strtoupper($this->charset) != ‘UTF-8′){
$content = iconv($this->charset,’utf-8′,$content);
}else if(!empty($this->httpHead['charset']) && $this->httpHead['charset']!=’UTF-8′)
{
$content = iconv($this->httpHead['charset'],’utf-8′,$content);
}
$this->httpreferer = $referer;
return $content;
}

/**
* 按照规则从内容提取所有字段
* @param Array
* @return Array
*/
function filterContent($content=”)
{
$rs = array();
foreach ($this->field_arr as $field => $fieldinfo){
$rs[$field] = $this->getPregField($fieldinfo,$content);
}
$this->result[] = $rs;
}
/**
* 相对路径转化为绝对路径
*
* @param string $relative
* @param string $referer
* @return string
*/
function urlRtoA($relative,$referer)
{
/**
* 去除#后面的部分
*/
$pos = strpos($relative,’#');
if($pos >0)$relative = substr($relative,0,$pos);
/**
* 检测路径如果是绝对地址直接返回
*/
if(preg_match(“~^(http|ftp)://~i”,$relative))
return $relative;
/**
* 解析引用地址,获得协议,主机等信息
*/
preg_match(“~((http|ftp)://([^/]*)(.*/))([^/#]*)~i”, $referer, $preg_rs);
$parentdir = $preg_rs[1];
$petrol = $preg_rs[2].’://’;
$host = $preg_rs[3];
/**
* 如果以/开头的情况
*/
if(preg_match(“~^/~i”,$relative))
return $petrol.$host.$relative;
return $parentdir.$relative;
}

/**
* 根据规则提取一个字段
*
* @param string $pattern
* @param string $content
* @return string
*/
function getPregField($fieldinfo,$content)
{
/**
* 规则为固定值的情况,直接返回固定值
*/
if(strpos($fieldinfo['pattern'],’{‘.$fieldinfo['field'].’}') === false)
return $fieldinfo['pattern'];
if($fieldinfo['isregular'] == ‘true’){
$pattern = $fieldinfo['pattern'];
$pattern = str_replace(‘{‘.$fieldinfo['field'].’}',’(?P<'.$fieldinfo['field'].'>.*?)’,$pattern);
}else{
$pattern = preg_quote($fieldinfo['pattern']);
$pattern = str_replace(‘\{‘.$fieldinfo['field'].’\}’,'(?P<'.$fieldinfo['field'].'>.*?)’,$pattern);
}
$pattern = “~”.$pattern.”~is”;
preg_match($pattern,$content,$preg_rs);
$fieldresult = $preg_rs[$fieldinfo['field']];
/**
* 去掉换行符
*/
$fieldresult = preg_replace(“~[\r\n]*~is”,”,$fieldresult);
/**
* 对采集到的结果根据规则再进行二次替换处理
*/
$replace_arr = $fieldinfo['replace'];
if(is_array($replace_arr)){
$replace_arr[0] = “~”.$replace_arr[0].”~s”;
$fieldresult = preg_replace($replace_arr[0],$replace_arr[1],$fieldresult);
}
/**
* 针对有下一页的字段递归采集
*/
if($this->pagelimit == 0){
if($fieldinfo['nextpage'] != ”){
$pattern = $fieldinfo['nextpage'];
$pattern = str_replace(‘{nextpage}’,'(?P[^\'\">]*?)’,$pattern);
$pattern = “~”.$pattern.”~is”;
if(preg_match($pattern,$content,$preg_rs) && $preg_rs['nextpage'] != ”){
$fieldresult .= $this->getPregField($fieldinfo,$this->getContent($preg_rs['nextpage'],$this->httpreferer));
}
}
}
if(!empty($fieldinfo['callback']))$fieldresult = $fieldinfo['callback']($fieldresult);
return $fieldresult;
}
/**
* 添加一个采集字段和规则
*
* @param string $field
* @param string $pattern
*/
function addField($field,$pattern,$replace_arr=”,$isregular=’false’,$nextpage = ”,$callback=”)
{
$rs = array(
‘field’ => $field,
‘pattern’ => $pattern,
‘replace’ => $replace_arr,
‘isregular’ => $isregular,
‘nextpage’ => $nextpage,
‘callback’=>$callback
);
$this->field_arr[$field] =$rs;
}
/**
* 输出
*
*/
function output()
{
echo “The result is:
“;
echo “runtime :$this->runtime S

";
		print_r($this->result);
		echo "

“;
}
/**
* 输出到XLS文件
*
* @param string $file
*/
function saveXls($file = ‘spider_result.xls’)
{
$fp = fopen($file,’w');
if($fp){
foreach ($this->result as $result)
{
$line = implode(“\t”,$result).”\n”;
fputs($fp,$line);
}
}
fclose($fp);
echo ‘The result has been saved to ‘.$file.’.
Cost time:’.$this->runtime;
}

function saveSql($table = ‘spider_result’,$file = ‘spider_result.sql’)
{
$fp = fopen($file,’w');
if($fp){

foreach($this->field_arr as $fieldinfo){
$sql_key .= ‘, `’.$fieldinfo['field'].’`';
}
$sql_key = substr($sql_key,1);
foreach ($this->result as $result)
{
$sql_value = array();
foreach ($result as $key => $value){
$sql_value[] = “‘”.$this->addslash($value).”‘”;
}
$line =”INSERT INTO `$table` ( $sql_key ) VALUES (“.join(‘, ‘,$sql_value).”);\r\n”;
fputs($fp,$line);
}
}
fclose($fp);
echo ‘The result has been saved to ‘.$file.’.
Cost time:’.$this->runtime;
}
/**
* 取得响应内容的头部信息
*
* @param string $content
* @return array
*/
function getHead($content)
{
$head = explode(“\r\n\r\n”,$content);
$head = $head[0];
// echo $head;
if(!preg_match(“~charset\=(.*)\r\n~i”,$head,$preg_rs))
preg_match(‘~charset=([^\"\']*)~i’,$content,$preg_rs);
$this->httpHead['charset'] = strtoupper(trim($preg_rs[1]));
// preg_match(“~charset\=(.*)~i”,$head,$preg_rs);
return $this->httpHead;
}
/**
* 设置采集页面的编码
* 在程序不能自动识别的情况下采集前要手动调用此函数
*
* @param string $charset
*/
function setCharset($charset){
$this->charset = strtoupper($charset);
}

/**
* 设置第一层链接页面地址
*
* @param array $url_arr
*/
function setStartUrls($url_arr)
{
$this->startUrls = $url_arr;
}

/**
* 增加一个第一层链接页面地址
*
* @param string $url
*/
function addStartUrl($url)
{
$this->startUrls[] = $url;
}
/**
* 添加一个采集层次
*
* @param integer $deep
* @param string $layout
* @param boolean $isSimple
* @param boolean $isPageBreak
* @param string $pattern
*/
function addLayer($deep,$layout,$pattern = ”,$isSimple = ‘false’,$isPageBreak = ‘false’)
{
$this->layout_arr[$deep] = array(
‘layout’=>$layout,
‘isSimple’=>$isSimple,
‘isPageBreak’=>$isPageBreak,
‘pattern’=>$pattern );

}

/**
* 自定义head
* @param string $namespace
* @param string $value
*/
function setHead($name,$value)
{
$this->putHead[$name] = $value;
}

/**
* 清除html代码
* @param string $content;
* @param string $cleartags
* @return string
*/
function clearHtml($content,$cleartags = ‘div’)
{
$cleartags_arr = explode(‘|’,$cleartags);

foreach ($cleartags_arr as $cleartag){
$pattern = ‘~<\/?'.$cleartag.'[^>]*>~is’;
$content = preg_replace($pattern,”,$content);
}
return $content;
}
/**
* 日志
*
*/
function log($str)
{
echo $str.”
\n”;
}
/**
* 获取采集运行时间
*
* @return float
*/
function getRuntime()
{
return $this->runtime;
}

function microtime_float()
{
list($usec, $sec) = explode(” “, microtime());
return ((float)$usec + (float)$sec);
}

function addslash($string)
{
return addslashes($string);
}
}

$spider = new spider();
$spider->addStartUrl(‘http://hi.baidu.com/shuntian/blog/index/{0,5}’);
$spider->setCharset(‘gb2312′);
$spider->addLayer(0,’list’,'/shuntian/blog/item/{*}.html’);
$spider->addField(‘title’,’‘,array(‘_顺者的天空-shooting's sky ‘,”));
$spider->addField(‘body’,’

{body}

‘);
$spider->addField(‘author’,'shooting’);
$spider->run();
$spider->saveSql();

我的wordpress图形验证码插件Wp-validcode

2009年10月25日 8 条评论

今天一天收到了65个垃圾评论,于是在前一个php验证码的基础上做出了自己的第一个wordpress插件,case见本站,下载地址在下面

wp-validcode

解压上传到wp-content/plugins目录,从后台安装即可!

已经调整为不区分大小写,验证码背景也进行了更换,更简单,但更具干扰性