用PHP处理中文PDF

Posted on 十二月 20th, 2008 in Program | No Comments »

因项目需要,现在想在服务器端动态生成PDF文件,已一个PDF为模板,然后把所需的数据动态填入。
本来在使用zend framework,因此很直接的就使用zend_pdf类来进行测试,代码实现如下:

$pdf = Zend_Pdf::load($this->view->config->offline->template);
$pdf->pages = array_reverse($pdf->pages);
$style = new Zend_Pdf_Style();
$font = Zend_Pdf_Font::fontWithPath($this->view->config->offline->font, ( Zend_Pdf_Font::EMBED_DONT_SUBSET));
$pdf->pages[0]->setFont($font, 10);
$pdf->pages[0]->saveGS();
//datalist
$pdf->pages[0]->drawText(str_replace(";","\n",$datalist), 100, 570,"UTF-8");
//project
$pdf->pages[0]->drawText($formData['project'], 100, 430,"UTF-8");
$pdf->pages[0]->drawText($formData['realname'], 100, 78,"UTF-8");
$pdf->pages[0]->drawText($formData['realname'], 130, 590,"UTF-8");
$pdf->pages[0]->drawText($formData['unit'], 95, 58,"UTF-8");
$pdf->pages[0]->drawText($formData['address'], 285, 58,"UTF-8");
$pdf->pages[0]->drawText($formData['postcode'], 470, 58,"UTF-8");
$pdf->pages[0]->drawText($formData['email'], 95, 40,"UTF-8");
$pdf->pages[0]->drawText($formData['phone'], 295, 40,"UTF-8");
$t=getdate();
$pdf->pages[0]->drawText($t['year'], 465, 40,"UTF-8");
$pdf->pages[0]->drawText($t['mon'], 500, 40,"UTF-8");
$pdf->pages[0]->drawText($t['mday'], 525, 40,"UTF-8");
$pdf->pages[0]->restoreGS();
$fn=$formData['realname'].date('YmdHis').".pdf";
$pdf->save($this->view->config->offline->savepath."/".$fn);

这样,的确能完成要求,但是令人恼火的是,其把中文字体内嵌到PDF文件中去,因此导致PDF文件过大,而且导致PHP所需内存也增大(64M)。
因此,就开始尝试别的办法,开始锁定fpdf,PHP能完美支持,而且也能支持中文(所要单独下载chinese.php和chinese-unicode.php)。
但是,FPDF不支持打开已有的PDF文件作为模板,因此还需要使用fpdi进行模板的支持,还要修改fpdi,使其父类为PDF-UNICODE。

然后就可以这样使用:

$pagecount = $this->setSourceFile($this->template);
$tplidx = $this->importPage(1, '/MediaBox');
$this->addPage();
$this->useTemplate($tplidx);
$this->AddUniGBhwFont('ugb','AdobeSongStd-Light-Acro');

$this->SetFont('ugb','',$this->fontsize);
$this->setXY(45,65);
$this->Write($this->fontsize,$this->data['realname']);

其中,字形由默认的AdobeSongStd-Light改成AdobeSongStd-Light-Acro,是为了防止英文字体变宽和变窄,格式才会整齐,英文字不会挤在一起。(参考: http://bbs.erp100.com/thread-18424-1-1.html)

ubuntu hardy下使用zend framework

Posted on 七月 22nd, 2008 in Linux | No Comments »

安装:

sudo aptitude install zend-framework

补充操作:
1 添加Zend符号连接
sudo ln -s /usr/share/php/libzend-framework-php/Zend /usr/share/php/Zend
2 修补中文EMAIL的subject乱码
参考http://framework.zend.com/issues/browse/ZF-2532

use bcspamblock in zend form

Posted on 七月 2nd, 2008 in Computer | No Comments »

I want to integrate the bcspamblock and zend form, so first to do:
为了能自动防止机器人攻击,打算把bcspamblock整合到zend_form中。
1 创建element_bcSpamBlock.php文件,

<?php
class element_bcSpamBlock extends Zend_Form_Element_Xhtml{
/**
* Default form view helper to use for rendering
* @var string
*/
public $helper = 'bcSpamBlock';
}

2 创建helper文件:BcSpamBlock.php

<?php
include_once("bcspamblock.php");
class Zend_View_Helper_BcSpamBlock extends Zend_View_Helper_FormElement{

public function bcSpamBlock($name, $value='', $attribs = null){

$xhtml = bcspamblock_generate(true);
return $xhtml;
}
}

3 创建validator,但奇怪的是,这一步经测试,没发生实际作用,不知道是什么原因。

<?php
include_once("bcspamblock.php");
class Validator_SpamBlock extends Zend_Validate_Abstract {
const NOT_MATCH = '机器人阻止';//'spam blocked!';

protected $_messageTemplates = array(
self::NOT_MATCH => '机器人阻止'
);

public function isValid($value) {
$result=bcspamblock_verify();
return $result;
}
}

4 创建自定义的form

<?php

class ContactForm extends Zend_Form
{
public function __construct($options = null)
{
parent::__construct($options);
$this->setName('Contact');

$username = new Zend_Form_Element_Text('username');
$username->setLabel('用户名')->setRequired(true)
->addFilter('StripTags') ->addFilter('StringTrim')
->addValidator('StringLength',false,array(3,50));

$email=new Zend_Form_Element_Text('email');
$email->setLabel('E-Mail')
->setRequired(true)
->addFilter('StringTrim')
->addValidator('NotEmpty')
->addValidator('EmailAddress');

$subject=new Zend_Form_Element_Text('subject');
$subject->setLabel('主题')->setRequired(true);

$body=new Zend_Form_Element_Textarea('body');
$body->setLabel('内容')->setRequired(true)->setAttrib('rows',4);

$id = new Zend_Form_Element_Hidden('id');

$submit = new Zend_Form_Element_Submit('submit');
$submit->setAttrib('id', 'submitbutton')->setLabel('发送');

$spam=new element_bcSpamBlock('spam');
$spam->addPrefixPath('Validator','validator/','validate')
->addValidator('SpamBlock');

$this->addElements(array($id, $spam,$username,$email,$subject,$body,$submit));
}
}

5 在action中调用此form

function contactAction()
{
$form=new ContactForm();
$this->view->form=$form;
$this->view->addHelperPath('helper','Zend_View_Helper_');
if ($this->_request->isPost()) {
//发送邮件
$formData=$this->_request->getPost();
include_once("bcspamblock.php");
if (bcspamblock_verify() && $form->isValid($formData)) {
$mail=new Zend_Mail('utf-8');
....

因为第3步中的validator自动调用不成功,因此在此进行了手工的判断。

生成UUID/GUID

Posted on 十一月 13th, 2007 in Program | 1 Comment »

php的生成办法:

<?php
class System
{
function currentTimeMillis()
{
list($usec, $sec) = explode(" ",microtime());
return $sec.substr($usec, 2, 3);
}

}

class NetAddress
{

var $Name = 'localhost';
var $IP = '127.0.0.1';

function getLocalHost() // static
{
$address = new NetAddress();
$address->Name = $_ENV["COMPUTERNAME"];
$address->IP = $_SERVER["SERVER_ADDR"];

return $address;
}

function toString()
{
return strtolower($this->Name.'/'.$this->IP);
}

}

class Random
{
function nextLong()
{
$tmp = rand(0,1)?'-':'';
return $tmp.rand(1000, 9999).rand(1000, 9999).rand(1000, 9999).rand(100, 999).rand(100, 999);
}
}

// 三段
// 一段是微秒 一段是地址 一段是随机数
class Guid
{

var $valueBeforeMD5;
var $valueAfterMD5;

function Guid()
{
$this->getGuid();
}
//
function getGuid()
{
$address = NetAddress::getLocalHost();
$this->valueBeforeMD5 = $address->toString().':'.System::currentTimeMillis().':'.Random::nextLong();
$this->valueAfterMD5 = md5($this->valueBeforeMD5);
}

function newGuid()
{
$Guid = new Guid();
return $Guid;
}

function toString()
{
$raw = strtoupper($this->valueAfterMD5);
return substr($raw,0,8).'-'.substr($raw,8,4).'-'.substr($raw,12,4).'-'.substr($raw,16,4).'-'.substr($raw,20);
}

}
?>

然后就可以这样调用:

1. <?php
2. require_once("guid.class.php");
3. $Guid = new Guid();
4. print $Guid->toString();
5. ?>

linux下可以用uuidgen命令来生成UUID,也可以在c/c++程序里调用:

/* clear.c */
void uuid_clear(uuid_t uu);

/* compare.c */
int uuid_compare(const uuid_t uu1, const uuid_t uu2);

/* copy.c */
void uuid_copy(uuid_t dst, const uuid_t src);

/* gen_uuid.c */
void uuid_generate(uuid_t out);
void uuid_generate_random(uuid_t out);
void uuid_generate_time(uuid_t out);

/* isnull.c */
int uuid_is_null(const uuid_t uu);

/* parse.c */
int uuid_parse(const char *in, uuid_t uu);

/* unparse.c */
void uuid_unparse(const uuid_t uu, char *out);

/* uuid_time.c */
time_t uuid_time(const uuid_t uu, struct timeval *ret_tv);
int uuid_type(const uuid_t uu);
int uuid_variant(const uuid_t uu);

在ubuntu下,需要确认已经安装对应的库:

sudo aptitude install libuuid1 uuid-dev

PHP的Framework

Posted on 十二月 11th, 2006 in Program | No Comments »

很长时间没有关注PHP,今天无意中点到javaeye.com,发现其已经改版,使用了ruby on rails框架技术,做得很好,然后又看到了还有php相关的框架,最近最近一段时间在PHP的世界里也出现了很多框架。作为php的发行公司,Zend自己也推出了一个框架,简称为ZF,目前最新的稳定版本还是0.2。觉得php的动作有点慢了,应该在php5推出后,要是能紧跟就推出几个框架系统,那对于php世界应该有非常大的推动!不过,虽然动作慢了一些,但是已经有了很多的php框架发展起来了。粗粗阅读了zf的文档后,发现框架的功能还是蛮丰富的,但是ZF目前还是有相当多的进步空间的,就是说,目前还是有一些缺点的。

一些framework的比较:

http://www.mustap.com/phpzone_post_73_top-10-php-mvc-frameworks

http://www.phpit.net/article/ten-different-php-frameworks/

http://www.5itag.com/viewtopic.php/177

seagull感觉像是一个大的CMS系统
ZF感觉像是一个库,或者就是pear
最后看了symfony的manual,感觉symfony相当好,不过也有缺陷,就是配置太麻烦了。
在symfony中,用Propel实现了OR映射,支持多种数据库,包括mysql,sqlserver,pgsql,sqlite,oracle。
感觉这套框架和zend framework有很大不同,对我来说,symfony要好于zf。
还支持schema, or map, paging, multitype databases, ...

Conclusion: 首选symfony,其次cakephp,最后再考虑zf。当然还可以考虑seagull。

php4+mysql 4.1的问题

Posted on 八月 31st, 2005 in eLearn | 2 Comments »

php4+mysql 4.1的问题
以前的一个考试系统,在PHP4+MYSQL 3的环境下进行开发的。
今天转到XP的APACHE 2 + PHP 4+ MYSQL 4.1环境下居然无法使用。提示PHP4无法连接数据库。
经过GOOGLE才发现是MYSQL 4.1修改了加密算法,需要处理一下才可以:
进入mysql
然后执行,
SET PASSWORD FOR 'some_user'@'some_host' = OLD_PASSWORD('newpwd');

另外还有一个中文乱码问题:
本来用的是GB2312编码,为了扩大系统的应用范围,想改成UTF8编码。程序改好后,发现从MYSQL提出来的数据都是GB2312编码,然后mysqldump在iconv -f gb2312 -t utf8,但有的数据无法转换,经检查是图像在数据库中的存贮部分,就把那个表单独给dump出来,然后在转换剩下的部分,大功告成。

php mapscript msGetLabelSize() 错误

Posted on 三月 15th, 2005 in MapServer | No Comments »

当出现这种错误时,而直接使用shp2img可以生成图象时,请检查你的PHP中的--with-gd参数后面是否指定了具体的gd路径.
Warning: MapServer Error in msGetLabelSize(): libgd was not built with FreeType font support in

debian sarge的PHP4的编译参数

Posted on 二月 25th, 2005 in Linux | 1 Comment »

debian中默认的PHP4编译参数,太长了,导致MAPSERVER的MAPSCRIPT无法编译。

'./configure' '--prefix=/usr' '--with-apxs2=/usr/bin/apxs2' '--with-regex=system' '--with-config-file-path=/etc/php4/apache2' '--disable-rpath' '--enable-memory-limit' '--disable-debug' '--with-layout=GNU' '--with-pear=/usr/share/php' '--enable-calendar' '--enable-sysvsem' '--enable-sysvshm' '--enable-sysvmsg' '--enable-track-vars' '--enable-trans-sid' '--enable-bcmath' '--with-bz2' '--enable-ctype' '--with-db4' '--with-iconv' '--enable-exif' '--enable-filepro' '--enable-ftp' '--with-gettext' '--enable-mbstring' '--with-pcre-regex=/usr' '--enable-shmop' '--enable-sockets' '--enable-wddx' '--disable-xml' '--with-expat-dir=/usr' '--with-xmlrpc' '--enable-yp' '--with-zlib' '--with-pgsql' '--with-kerberos=/usr' '--with-openssl=/usr' '--enable-dbx' '--with-mime-magic=/usr/share/misc/file/magic.mime' '--with-exec-dir=/usr/lib/php4/libexec' '--disable-static' '--with-curl=shared,/usr' '--with-dom=shared,/usr' '--with-dom-xslt=shared,/usr' '--with-dom-exslt=shared,/usr' '--with-zlib-dir=/usr' '--with-gd=shared,/usr' '--enable-gd-native-ttf' '--with-jpeg-dir=shared,/usr' '--with-xpm-dir=shared,/usr/X11R6' '--with-png-dir=shared,/usr' '--with-freetype-dir=shared,/usr' '--with-imap=shared,/usr' '--with-imap-ssl' '--with-ldap=shared,/usr' '--with-mcal=shared,/usr' '--with-mhash=shared,/usr' '--without-mm' '--with-mysql=shared,/usr' '--with-unixODBC=shared,/usr' '--with-recode=shared,/usr' '--enable-xslt=shared' '--with-xslt-sablot=shared,/usr' '--with-snmp=shared,/usr' '--with-ttf=shared,/usr' '--with-t1lib=shared,/usr' '--with-gd=shared,/usr' '--with-mysql=shared,/usr'

php的http类

Posted on 十二月 25th, 2004 in Program | 评论关闭

一个好用的http类,只有一个文件,适合很小的程序使用,可以用来模拟POST,支持文件上传和Cookie。
若以后要实现EDD的跨平台PHP方案,可能会使用此类.

http://new21.mirrors.phpclasses.org/browse/package/576.html

apache/php/mysql的安装

Posted on 十二月 22nd, 2004 in Linux | No Comments »

虽然已经安装过多次了,还是记录一下这次安装的过程。

cd ~
wget http://apache.freelamp.com/httpd/httpd-2.0.52.tar.gz
tar xzf httpd-2.0.52.tar.gz
wget http://cn.php.net/get/php-4.3.10.tar.gz/from/this/mirror
tar xzf php-4.3.10.tar.gz
cd ~/httpd-2.0.52
#make clean
./configure --enable-rewrite --enable-so
make
make install
cd ~/php-4.3.10
#make clean
./configure --with-apxs2=/usr/local/apache2/bin/apxs
make
make install
cd ~
wget http://dev.mysql.com/get/Downloads/\
MySQL-4.0/mysql-standard-4.0.23-pc-linux-i686.tar.gz/\
from/http://mysql.zawodny.com/