2005年07月23日

今天在检查转成的简体中文插件的时候发现modules\Activities\language\zh_cn.lang.php竟然是空的,我使用的是如下这个小程序转的

<?php
  include_once ‘ccharset.php’;
  $code=new CCharset();//
  include_once ‘gb2312.php’ ;
  $this->g2312 = new GB2312toUTF8();   
  $file=’zh_tw.lang.php’;    
  $fd=fopen($file,’r');    
  $contents = fread($fd, filesize($file));      
  $contents=iconv(‘UTF-8′,’BIG5′,$contents);
  echo $contents;//这里就显示内容为空了,说明执行上面的iconv的转换是出现了bug
  $contents=$code->Big5_Gb($contents);  
  $contents=$this->g2312->gb2utf8($contents);
  fclose($fd);
  $fd=fopen(str_replace(‘zh_tw’,'zh_cn’,$file),’w');
  fwrite($fd,$contents);
  fclose($fd); 
 ?>

再转其它的文件的时候都没有问题,于是我又试了下不使用iconv的方式(完全使用php脚本来实现的方法,改日会把整个实现类上传供大家分享)来实现上面的功能,发现可以正常转换,由此判定iconv可能有问题

我使用的php版本是4.3.11,iconv的版本是1.9.0.0

2005年07月17日
因为没有数据库的关系,我使用了一个免费的基于文本文件的统计程序(VERYOK 实用统计3.0 – 正式版 Build 0530),发现统计出来的IP都是127.0.0.1,一时也不知道是什么原因,当然也注意到getenv(‘REMOTE_ADDR’)在有些环境下能得到正确的IP,有些环境下却是不行。自己水平有限,于是求助google,找到下面这个答案,顺便把其中的bug改了过来,这下正常了。
上面提到的统计程序的修改方法很简单
打开statadd.php文件,查找到$user_ip=getenv("REMOTE_ADDR") 替换成$user_ip=GetIP();
当然别忘了把下面的GetIP()函数添加到该文件中,保持好就可以了。
P.S.
PHP Manual中提及的使用getenv(‘REMOTE_ADDR’)来获取客户端ip的方法存在不少问题,所以有必要考虑采用更为完善的方法来比较精确的获取用户客户端的ip。

getenv


(PHP 3, PHP 4, PHP 5)

getenv – Gets the value of an environment variable


Description

string getenv ( string varname )

Returns the value of the environment variable varname, or FALSE on an error.


<?php// Example use of getenv()$ip = getenv('REMOTE_ADDR');
// Or simply use a Superglobal ($_SERVER or $_ENV)$ip = $_SERVER['REMOTE_ADDR'];?>

这是在PHP官方的manual提供的方法。

但是当Web服务器API是ASAPI (IIS)的时候,getenv函数是不起作用的。这种情况下你如果用getenv来取得用户客户端ip的话,得到的将是错误的ip地址。

因此更为安全和准确的方法是尽量避免使用getenv函数。比如可以用以下的函数来获取ip信息:

//Get the real client IP ("bullet-proof")

function GetIP(){
  
if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
          
$ip = getenv("HTTP_CLIENT_IP");
      
else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
          
$ip = getenv("HTTP_X_FORWARDED_FOR");
      
else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
          
$ip = getenv("REMOTE_ADDR");
      
else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
          
$ip = $_SERVER['REMOTE_ADDR'];
      
else
          
$ip = "unknown";
  
return($ip);
}

更为详细的讨论请参见http://cn.php.net/manual/zh/function.getenv.php

2005年07月15日

在线上传PDF,并给PDF添加水印(watermark),邮戳(stamp),页码,页眉,页脚,支持中文,支持角度,中英文文字和图片,图片透明效果,以及罗马字。

还要个添加背景色的demo。

目前仅是demo,更多功能敬请期待中。

http://gmail.512j.com/friend/rocsky/pdftools/

2005年07月14日

在国外找个php的免费空间,上传phpproxy,然后浏览国内受限的网站,非法的你自己看着办吧,没有加密保护措施哟。

PHProxy is a web HTTP proxy programmed in PHP meant to bypass firewalls and access otherwise inaccessible resources (i.e. blocked websites). If the server this script is run on can access a resource, so can you!

网站:

http://sourceforge.net/projects/poxy/

直接下载地址:

http://switch.dl.sourceforge.net/sourceforge/poxy/poxy-0.3.zip

下面是个放在国内的demo,

http://gmail.512j.com/friend/rocsky/proxy/index.php

2005年07月08日

FPDI is a collection of PHP classes that allow developers to read pages from existing PDF documents and to use them as templates in FPDF by Olivier Plathey

FPDI – A free PHP class to import existing PDF documents into FPDF.

以上是Setasign 公司的Jan Slabon(FPDI的作者)对FPDI的介绍。

       从作者的介绍可以看出,FPDI可以让FPDF把PDF作为模板导入,这样以来就大大的增加了FPDF的功能,让FPDF不仅可以生成PDF,而且可以导入PDF并对它进行加工处理,也就是大家所期望的页眉,页脚,页码,水印,邮戳,背景色(另外一篇文章就介绍了背景色的程序),添加文字,等等一系列功能。

有兴趣的就赶快去试下吧,也许能为你的工作帮助不小呢。

目前FPDI的最新版本是v1.1,你可以到官方网站下载

http://fpdi.setasign.de/index.php

也可以到我的测试网站下载

http://steedsoft.hostrs.com/download/

        经常看到网上有人发帖询问如何真正修改PDF的背景色(是为了打印使用,不仅仅是为了看,因为Acrobat可以在浏览的时候根据个人喜好设置背景颜色和字体颜色的),最近刚好在学习PHP(为了研究FPDF),于是就写了一段代码(当然以前也写过java版本的,并且把它编译为exe程序,有兴趣的可以和我联系),通过对这段代码进行修改,你还可以增加更多的功能,比如水印,页眉页脚等,添加页码。如果大家觉得有必要我就完善下,并写个实用的程序来。

        运行如下代码,需要FPDF和FPDI,当然PHP的运行环境是少不了的了(不过你可以只要php.exe和php4ts.dll就够了,因为不需要额外的扩展函数)。

        所需类文件可以到如下网站下载:

http://steedsoft.hostrs.com/download/

或者从到其官方网站下载最新版本:

http://fpdi.setasign.de/index.php?p=downloads

http://www.fpdf.org/

<%php

ini_set(‘max_execution_time’,0);
define(‘FPDF_FONTPATH’,'font/’);
require(‘fpdi.php’);


class PDF extends fpdi{ 
 function Header(){
  global $r,$g,$b; 
  $this->SetFillColor($r,$g,$b);      
  $this->Rect(0,0,1400,1400,’F');
 }
}

$pdf=new PDF();
global $r,$g,$b;
switch ($argc) {
 case 4: $r=$argv[3];$g=-1; break;
 case 5:
 case 6:$r=$argv[3];$g=$argv[4];$b=$argv[5]; break;
 default: echo "Usage:php bgcolor.php inpdf outpdf red gree blue";
}

$pagecount = $pdf->setSourceFile($argv[1]);
for ($i=1;$i<=$pagecount;$i++){
 $tplidx = $pdf->ImportPage($i);
 $pdf->AddPage();
 $pdf->useTemplate($tplidx);
}
$pdf->Output($argv[2],"F");
$pdf->closeParsers();
?>

2005年07月07日

FPDF ports:
 www.aspxnet.it   (ASP):类由javascript完成,需要FSO的支持
 http://dasdeck.de/staff/valentin/lingo/pdf_class/   (Lingo):对这门语言一无所知

 http://brian.imxcc.com/fpdf/   (Ruby):一个预与Python相抗衡的脚本语言,与Python相比,各有千秋

2005年07月04日

因为仍在测试中,所以只是放了PDF文件上来,有兴趣的看看效果,呵呵,也算是留作纪念用的,第一个稍微有点样子的公章(当然文字还没有改成红色呢)。

使用了免费的FPDF类,一个改进的Circle类和一个Star函数,就生成了现在这个样子。

http://steedsoft.hostrs.com/download

2005年06月30日

使用如下代码

 switch (strtoupper(trim($format))){
   case ‘4A0′: {$format = array(4767.87,6740.79); break;}
   case ‘2A0′: {$format = array(3370.39,4767.87); break;}
   case ‘A0′: {$format = array(2383.94,3370.39); break;}
   case ‘A1′: {$format = array(1683.78,2383.94); break;}
   case ‘A2′: {$format = array(1190.55,1683.78); break;}
   case ‘A3′: {$format = array(841.89,1190.55); break;}
   case ‘A4′: {$format = array(595.28,841.89); break;}
   case ”: {$format = array(595.28,841.89); break;}
   case ‘A5′: {$format = array(419.53,595.28); break;}
   case ‘A6′: {$format = array(297.64,419.53); break;}
   case ‘A7′: {$format = array(209.76,297.64); break;}
   case ‘A8′: {$format = array(147.40,209.76); break;}
   case ‘A9′: {$format = array(104.88,147.40); break;}
   case ‘A10′: {$format = array(73.70,104.88); break;}
   case ‘B0′: {$format = array(2834.65,4008.19); break;}
   case ‘B1′: {$format = array(2004.09,2834.65); break;}
   case ‘B2′: {$format = array(1417.32,2004.09); break;}
   case ‘B3′: {$format = array(1000.63,1417.32); break;}
   case ‘B4′: {$format = array(708.66,1000.63); break;}
   case ‘B5′: {$format = array(498.90,708.66); break;}
   case ‘B6′: {$format = array(354.33,498.90); break;}
   case ‘B7′: {$format = array(249.45,354.33); break;}
   case ‘B8′: {$format = array(175.75,249.45); break;}
   case ‘B9′: {$format = array(124.72,175.75); break;}
   case ‘B10′: {$format = array(87.87,124.72); break;}
   case ‘C0′: {$format = array(2599.37,3676.54); break;}
   case ‘C1′: {$format = array(1836.85,2599.37); break;}
   case ‘C2′: {$format = array(1298.27,1836.85); break;}
   case ‘C3′: {$format = array(918.43,1298.27); break;}
   case ‘C4′: {$format = array(649.13,918.43); break;}
   case ‘C5′: {$format = array(459.21,649.13); break;}
   case ‘C6′: {$format = array(323.15,459.21); break;}
   case ‘C7′: {$format = array(229.61,323.15); break;}
   case ‘C8′: {$format = array(161.57,229.61); break;}
   case ‘C9′: {$format = array(113.39,161.57); break;}
   case ‘C10′: {$format = array(79.37,113.39); break;}
   case ‘RA0′: {$format = array(2437.80,3458.27); break;}
   case ‘RA1′: {$format = array(1729.13,2437.80); break;}
   case ‘RA2′: {$format = array(1218.90,1729.13); break;}
   case ‘RA3′: {$format = array(864.57,1218.90); break;}
   case ‘RA4′: {$format = array(609.45,864.57); break;}
   case ‘SRA0′: {$format = array(2551.18,3628.35); break;}
   case ‘SRA1′: {$format = array(1814.17,2551.18); break;}
   case ‘SRA2′: {$format = array(1275.59,1814.17); break;}
   case ‘SRA3′: {$format = array(907.09,1275.59); break;}
   case ‘SRA4′: {$format = array(637.80,907.09); break;}
   case ‘LETTER’: {$format = array(612.00,792.00); break;}
   case ‘LEGAL’: {$format = array(612.00,1008.00); break;}
   case ‘EXECUTIVE’: {$format = array(521.86,756.00); break;}
   case ‘FOLIO’: {$format = array(612.00,936.00); break;}
   default:   $this->Error(‘Unknown page format: ‘.$format);
  } 

替换FPDF中的如下代码

  $format=strtolower($format);
  if($format==’a3′)
   $format=array(841.89,1190.55);
  elseif($format==’a4′)
   $format=array(595.28,841.89);
  elseif($format==’a5′)
   $format=array(420.94,595.28);
  elseif($format==’letter’)
   $format=array(612,792);
  elseif($format==’legal’)
   $format=array(612,1008);
  else
   $this->Error(‘Unknown page format: ‘.$format);

  这样不但增进了更多常用的尺寸格式,而且通过字符串处理,你即使不小心在尺寸格式中敲入空格也没有关系了,以上代码根据http://www.ros.co.nz/pdf的PDFClass中部分代码修改而成,当然你也可以把这个尺寸格式和尺寸的对照表用于任何你感兴趣的程序代码中,比如以前我就专门写了一个Acrobat的javascript插件,专门用来生成标准格式(也可以自定义)的空白PDF文件。

2005年06月29日

例子参考:

Demo.php

<?php
//error_reporting (E_ALL);
define(‘FPDF_FONTPATH’,’../font/’);
require(‘../fpdf.php’);
require(‘Roman.php’);

class PDF extends fpdf

 //Page footer
 function Footer()
 {
  //Position at 1.5 cm from bottom
  $this->SetY(-15);
  //Arial italic 8
  $this->SetFont(‘Arial’,'I’,8);
  //Page number  
  $Roman= new Numbers_Roman();
  $this->Cell(0,10,$Roman->toRoman($this->PageNo()),0,0,’C');//默认转为大写  
 }
}

$pdf= new PDF();
$Roman= new Numbers_Roman();
for ($i = 1; $i <= 10; $i++) {
 $pdf->AddPage();
 $pdf->SetFont(‘Arial’,'B’,16);
 $pdf->Cell(40,10,’Page ‘.$Roman->toRoman($i,false));//显示小写罗马数字
}
$pdf->Output(‘roman.pdf’);
?>

Roman.php

<?php
//
// +———————————————————————-+
// | PHP Version 4                                                        |
// +———————————————————————-+
// | Copyright (c) 1997-2004 The PHP Group                                |
// +———————————————————————-+
// | This source file is subject to version 2.02 of the PHP license,      |
// | that is bundled with this package in the file LICENSE, and is        |
// | available at through the world-wide-web at                           |
// |
http://www.php.net/license/2_02.txt.                                 |
// | If you did not receive a copy of the PHP license and are unable to   |
// | obtain it through the world-wide-web, please send a note to          |
// |
license@php.net so we can mail you a copy immediately.               |
// +———————————————————————-+
// | Authors :  David Costa <
gurugeek@php.net>                            |
// |            Sterling Hughes <
sterling@php.net>                        |
// +———————————————————————-+
// $Id: Roman.php,v 1.14 2004/04/28 13:13:08 danielc Exp $

// {{{ Numbers_Roman

/**
 * Provides utilities to convert roman numerals to
 * arabic numbers and convert arabic numbers to roman numerals.
 *
 * Supports lower case input and output and some furthers conversion
 * functions.
 *
 * @access public
 * @author David Costa <
gurugeek@php.net>
 * @author Sterling Hughes <
sterling@php.net>
 * @package Numbers_Roman
 */
class Numbers_Roman
{
    // {{{ toNumber()

    /**
     * Converts a roman numeral to a number
     *
     * @param  string  $roman The roman numeral to convert
     *                        lower cased numerals are converted into
     *                        uppercase
     * @return integer $num   The number corresponding to the
     *                        given roman numeral
     * @access public
     */
    function toNumber($roman)
    {
        $roman = strtoupper($roman);

        /*
         * Replacing the Numerals representing an integer higher then 4000
         * e.g. _X represent 10 000 _L  represent 50 000 etc
         * we first convert them into single characters
         */
        $roman = str_replace(‘_V’, ‘S’, $roman);
        $roman = str_replace(‘_X’, ‘R’, $roman);
        $roman = str_replace(‘_L’, ‘Q’, $roman);
        $roman = str_replace(‘_C’, ‘P’, $roman);
        $roman = str_replace(‘_D’, ‘O’, $roman);
        $roman = str_replace(‘_M’, ‘N’, $roman);

        $conv = array(
            array(‘letter’ => ‘I’, ‘number’ => 1),
            array(‘letter’ => ‘V’, ‘number’ => 5),
            array(‘letter’ => ‘X’, ‘number’ => 10),
            array(‘letter’ => ‘L’, ‘number’ => 50),
            array(‘letter’ => ‘C’, ‘number’ => 100),
            array(‘letter’ => ‘D’, ‘number’ => 500),
            array(‘letter’ => ‘M’, ‘number’ => 1000),
            array(‘letter’ => ‘S’, ‘number’ => 5000),
            array(‘letter’ => ‘R’, ‘number’ => 10000),
            array(‘letter’ => ‘Q’, ‘number’ => 50000),
            array(‘letter’ => ‘P’, ‘number’ => 100000),
            array(‘letter’ => ‘O’, ‘number’ => 500000),
            array(‘letter’ => ‘N’, ‘number’ => 1000000),
            array(‘letter’ => 0, ‘number’ => 0)
        );

        $arabic = 0;
        $state = 0;
        $sidx = 0;
        $len = strlen($roman) – 1;

        while ($len >= 0) {
            $i = 0;
            $sidx = $len;

            while ($conv[$i]['number'] > 0) {
                if (strtoupper($roman[$sidx]) == $conv[$i]['letter']) {
                    if ($state > $conv[$i]['number']) {
                        $arabic -= $conv[$i]['number'];
                    } else {
                        $arabic += $conv[$i]['number'];
                        $state = $conv[$i]['number'];
                    }
                }
                $i++;
            }
            $len–;
        }

        return $arabic;
    }

    // }}}
    // {{{ toRoman()

    /**
     * A backwards compatibility alias for toNumeral()
     *
     * @access private
     */
    function toRoman($num, $uppercase = true)
    {
        return $this->toNumeral($num, $uppercase);
    }

    // }}}
    // {{{ toNumeral()

    /**
     * Converts a number to its roman numeral representation
     *
     * @param  integer $num         An integer between 0 and 3999
     *                              inclusive that should be converted
     *                              to a roman numeral integers higher than
     *                              3999 are supported from version 0.1.2
     *           Note:
     *           For an accurate result the integer shouldn’t be higher
     *           than 5 999 999. Higher integers are still converted but
     *           they do not reflect an historically correct Roman Numeral.
     *
     * @param  bool    $uppercase   Uppercase output: default true
     *
     * @param  bool    $html        Enable html overscore required for
     *                              integers over 3999. default true
     * @return string  $roman The corresponding roman numeral
     *
     * @access public
     */
    function toNumeral($num, $uppercase = true, $html = true)
    {
        $conv = array(10 => array(‘X’, ‘C’, ‘M’),
        5 => array(‘V’, ‘L’, ‘D’),
        1 => array(‘I’, ‘X’, ‘C’));
        $roman = ”;

        if ($num < 0) {
            return ”;
        }

        $num = (int) $num;

        $digit = (int) ($num / 1000);
        $num -= $digit * 1000;
        while ($digit > 0) {
            $roman .= ‘M’;
            $digit–;
        }

        for ($i = 2; $i >= 0; $i–) {
            $power = pow(10, $i);
            $digit = (int) ($num / $power);
            $num -= $digit * $power;

            if (($digit == 9) || ($digit == 4)) {
                $roman .= $conv[1][$i] . $conv[$digit+1][$i];
            } else {
                if ($digit >= 5) {
                    $roman .= $conv[5][$i];
                    $digit -= 5;
                }

                while ($digit > 0) {
                    $roman .= $conv[1][$i];
                    $digit–;
                }
            }
        }

        /*
         * Preparing the conversion of big integers over 3999.
         * One of the systems used by the Romans  to represent 4000 and
         * bigger numbers was to add an overscore on the numerals.
         * Because of the non ansi equivalent if the html output option
         * is true we will return the overline in the html code if false
         * we will return a _ to represent the overscore to convert from
         * numeral to arabic we will always expect the _ as a
         * representation of the html overscore.
         */
        if ($html == true) {
            $over = ‘<span style="text-decoration:overline;">’;
            $overe = ‘</span>’;
        } elseif ($html == false) {
            $over = ‘_’;
            $overe = ”;
        }

        /*
         * Replacing the previously produced multiple MM with the
         * relevant numeral e.g. for 1 000 000 the roman numeral is _M
         * (overscore on the M) for 900 000 is _C_M (overscore on both
         * the C and the M) We initially set the replace to AFS which
         * will be later replaced with the M.
         *
         * 500 000 is   _D (overscore D) in Roman Numeral
         * 400 000 is _C_D (overscore on both C and D) in Roman Numeral
         * 100 000 is   _C (overscore C) in Roman Numeral
         *  90 000 is _X_C (overscore on both X and C) in Roman Numeral
         *  50 000 is   _L (overscore L) in Roman Numeral
         *  40 000 is _X_L (overscore on both X and L) in Roman Numeral
         *  10 000 is   _X (overscore X) in Roman Numeral
         *   5 000 is   _V (overscore V) in Roman Numeral
         *   4 000 is M _V (overscore on the V only) in Roman Numeral
         *
         * For an accurate result the integer shouldn’t be higher then
         * 5 999 999. Higher integers are still converted but they do not
         * reflect an historically correct Roman Numeral.
         */
        $roman = str_replace(str_repeat(‘M’, 1000),
                             $over.’AFS’.$overe, $roman);
        $roman = str_replace(str_repeat(‘M’, 900),
                             $over.’C’.$overe.$over.’AFS’.$overe, $roman);
        $roman = str_replace(str_repeat(‘M’, 500),
                             $over.’D’.$overe, $roman);
        $roman = str_replace(str_repeat(‘M’, 400),
                             $over.’C’.$overe.$over.’D’.$overe, $roman);
        $roman = str_replace(str_repeat(‘M’, 100),
                             $over.’C’.$overe, $roman);
        $roman = str_replace(str_repeat(‘M’, 90),
                             $over.’X’.$overe.$over.’C’.$overe, $roman);
        $roman = str_replace(str_repeat(‘M’, 50),
                             $over.’L’.$overe, $roman);
        $roman = str_replace(str_repeat(‘M’, 40),
                             $over.’X’.$overe.$over.’L’.$overe, $roman);
        $roman = str_replace(str_repeat(‘M’, 10),
                             $over.’X’.$overe, $roman);
        $roman = str_replace(str_repeat(‘M’, 5),
                             $over.’V’.$overe, $roman);
        $roman = str_replace(str_repeat(‘M’, 4),
                             ‘M’.$over.’V’.$overe, $roman);

        /*
         * Replacing AFS with M used in both 1 000 000
         * and 900 000
         */
        $roman = str_replace(‘AFS’, ‘M’, $roman);

        /*
         * Checking for lowercase output
         */
        if ($uppercase == false) {
            $roman = strtolower($roman);
        }

        return $roman;
    }

    // }}}

}

// }}}

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */

?>