Posts Tagged ‘php’

php怎么将字符转换成特定编码

Posted by 机器人 on 5th 一月 2009 in php/javascript

当我们在接受未知客户端提交的数据,由于各客户端的编码不统一,但在我们的服务器端最终只能以一种编码方式来处理,这种情况下就会涉及到一个将接受到的字符转换为特定编码的问题。

这时可能会想到直接用iconv来进行转码,但我们知道,iconv这个函数需要提供的两个参数为输入编码和输出编码,而我们现在根本不知道接受的字符串是什么编码,如果这个时候能得到接收字符是什么编码就好了。
对于这样的问题,一般会有两种解决方案。
方案一:
要客户端提交数据时,指定所提交的编码,这时就需要多给一个用来指定编码的变量。

$string = $_GET['charset'] === 'gbk' ? iconv('gbk','utf-8',$_GET['str']) : $_GET['str'];

对于这种情况,如果在没有约定或者我们不能控制客户端的情况下,似乎这种方案使用不是很好。
方案二
直接由服务器端来检测所接收的数据编码。
这种方案当然是最理想了的了,现在问题是怎么检测一个字符的编码吗?对于这种情况,在php里,mb_string这个扩展中的mb_check_encoding提供了我们所需要的功能。

$str = mb_check_encoding($_GET['str'],'gbk') ? iconv('gbk','utf-8',$_GET['str']) : $_GET['str'];

但这需要打开mb_string这个扩展,有些时候可能我们的生产服务器中没有打开这个扩展。对于这种情况,需要自己借助如下函数来判断编码。
以下函数非本人所写

function isGb2312($string) {
	for($i=0; $i 127) {
			if( ($v >= 228) && ($v < = 233) )
			{
				if( ($i+2) >= (strlen($string) - 1)) return true;
				$v1 = ord( $string[$i+1] );
				$v2 = ord( $string[$i+2] );
				if( ($v1 >= 128) && ($v1 < =191) && ($v2 >=128) && ($v2 < = 191) )
					return false;
				else
					return true;
			}
		}
	}
	return true;
}
function isUtf8($string) {
	return preg_match('%^(?:
	[\x09\x0A\x0D\x20-\x7E] # ASCII
	| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
	| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
	| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
	| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
	| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
	| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
	)*$%xs', $string);
}

这里我们就可以使以上任何一个函数来实现编码的检测。并将其转换成指定的编码。

$str = isGb2312($_GET['str'],'gbk') ? iconv('gbk','utf-8',$_GET['str']) : $_GET['str'];

机器人 2008-01-05 22:18 于 北京

nginx0.6.34+php-5.27 fastcgi 安装

Posted by 机器人 on 8th 十二月 2008 in linux/server

所需包:
php-5.2.7.tar.bz2
nginx-0.6.34
lighttpd-1.4.20.tar.gz
mysql-5.0.67.tar.gz

编译安装mysql-6.0.67

hqlong@ubuntu:~/software/tar.gz$ tar zxvf mysql-5.0.67.tar.gz 
hqlong@ubuntu:~/software/tar.gz$ cd mysql-5.0.67/
hqlong@ubuntu:~/software/tar.gz/mysql-5.0.67$ ./configure \
--prefix=/usr/local/webserver/mysql/ \
--without-debug \
--with-unix-socket-path=/tmp/mysql.sock \
--with-client-ldflags=-all-static \
--with-mysqld-ldflags=-all-static --enable-assembler \
--with-extra-charsets=gbk,gb2312,utf8 \
--with-pthread \
--enable-thread-safe-client
hqlong@ubuntu:~/software/tar.gz/mysql-5.0.67$ make && sudo make install
hqlong@ubuntu:~/software/tar.gz/mysql-5.0.67$ sudo chmod +w /usr/local/webserver/mysql
hqlong@ubuntu:~/software/tar.gz/mysql-5.0.67$ sudo chown -R mysql:mysql /usr/local/webserver/mysql
hqlong@ubuntu:~/software/tar.gz/mysql-5.0.67$ cp support-files/my-medium.cnf /usr/local/webserver/mysql/my.cnf

Read the rest of this entry »

几步创建您的php扩展

Posted by 机器人 on 16th 十一月 2008 in c/c++, linux/server

下面以开发hello world这个简单的应用扩展为例,来说明开发的步骤,这个扩展提供一个hello_world()函数,该函数会返回一个”hello world”字符串,在php中的调用方式如下:

< ?php
    echo hello_world();
?>

首先进入php源码中的ext目录,php的所有扩展库的源码都放在这里。
然后创建hello目录,这个目录里就存放我们helloworld扩展的源码和相关文件.
Read the rest of this entry »

apache、php、mysql源码安装

Posted by 机器人 on 13th 四月 2008 in linux/server

这里,我选择了CentOS来作为我的安装系统,当然也可以选择其它的发行版。

最小化安装系统

需要额外软件包

libjpeg-devel-6b-33

freetype-devel-2.1.9-6.el4

zlib-devel-1.2.1.2-1.2

libpng-devel-1.2.7-3.el4_5.1

gd-devel-2.0.28-5.4E

gd-2.0.28-5.4E

glibc-devel-2.3.4-2.39

gcc-3.4.6-9

glibc-kernheaders-2.4-9.1.100.EL

glibc-headers-2.3.4-2.39

以前软件最好去linux镜像中去找,这样就不需要为版本的不兼容麻烦了。

首先下载我们所需要的安装包

1. httpd-2.2.8.tar.gz

2. php-5.2.5.tar.gz

3. mysql-5.1.23-rc.tar.gz

将其放在/etc/local/src目录中。

1.安装apache服务器。

[root@localhost ~]# cd /usr/local/src
[root@localhost ~]# tar zxvf httpd-2.2.8.tar.gz
[root@localhost ~]# cd httpd-2.2.8
[root@localhost ~]# ./configure \
--prefix=/usr/local/apache \
--enable-mpm-worker \
--enable-so \
--enable-rewrite \
--enable-cache \
--enable-disk-cache \
--enable-mem-cache \
--enable-file-cache
[root@localhost ~]# make
[root@localhost ~]# make install

选项说明

–prefix=/usr/local/apache

将apache安装到/usr/local/apache,方便管理

–enable-mpm-worker

设置apache多任务处理,默认为–enable-mpm-prefork

其中prefork为,每建立一个连接,就建立一个进程,即,多进程并行处理,

而worker则为多线程并行处理,对于高流量的服务器来说,worker将比prefork节省更多的内存

更多请参见手册 http://httpd.apache.org/docs/2.0/mpm.html

–enable-so

so模块用来提供DSO支持的apache核心模块。

–enable-rewrite

打开URL重写模块

–enable-cache

–enable-disk-cache

–enable-mem-cache

–enable-file-cache

详细说明请参见     http://httpd.apache.org/docs/2.2/caching.html

2. mysql安装

[root@localhost ~]# cd /usr/local/src
[root@localhost ~]# tar mysql-5.1.23-rc.tar.gz
[root@localhost ~]# cd mysql-5.1.23-rc
[root@localhost ~]# ./configure \
--prefix=/usr/local/mysql \
--localstatedir=/usr/local/mysql/data \
--disable-maintainer-mode \
--with-mysqld-user=mysql \
--with-unix-socket-path=/tmp/mysql.sock \
--without-comment \
--without-debug \
--with-bench
[root@localhost ~]# make
[root@localhost ~]# make install

接下来为专门为MYSQL创建一个用户和一个用户组

[root@localhost ~]# groupadd mysql
[root@localhost ~]# useradd mysql -g mysql

mysql的用户在上面的配置中已经指定。

接下来安装系统数据库。

[root@localhost ~]# cd scripts/
[root@localhost ~]# ./mysql_install_db

设置相应目录权限

[root@localhost ~]# chown -R mysql:mysql /usr/local/mysql
[root@localhost ~]# chown -R mysql:mysql /usr/local/mysql/data

拷贝配置文件到/etc目录下

[root@localhost ~]# cd support-files/
[root@localhost ~]# cp my-medium.cnf /etc/my.cnf

后台启动mysql

[root@localhost ~]# cd /usr/local/mysql/bin
[root@localhost ~]# ./mysqld_safe &

如果要查看当前状态,启动服务器,可以通过如下方法

[root@localhost ~]# cd /usr/local/mysql/share/mysql
[root@localhost ~]# ./mysql.server [status|stop|start|restart]

3. php安装

[root@localhost ~]# cd /usr/local/src
[root@localhost ~]# tar zxvf php-5.2.5.tar.gz
[root@localhost ~]# cd php-5.2.5
[root@localhost ~]# ./configure \
--prefix=/usr/local/php \
--with-apxs2=/usr/local/apache/bin/apxs \
--enable-safe-mode \
--with-mysql=/usr/local/mysql \
--with-pdo-mysql=/usr/local/mysql/ \
--with-gd \
--with-jpeg-dir=/usr \
--with-png-dir=/usr \
--without-pear
[root@localhost ~]# make
[root@localhost ~]# make install

拷贝php配置文件

cp php-ini-dest /usr/local/php/lib/php.ini

打开apache配置文件

vi /usr/loca/apache/conf/httpd.conf

查看libphp5.so

如果能找到,则说明php编译没有总是,否则重新编译

添加php文件后缀支持

AddType application/x-httpd-php .php

4.后续工作

把apache和mysql加到启动启动文件中

[root@localhost ~] vi /etc/rc.d/rc.local
/usr/local/apache/bin/apachectl start
/usr/local/mysql/bin/mysqld_safe --user=mysql &

5.安装时可能出现的总是及解决方法

Q. checking for termcap functions library… configure: error: No curses/termcap library

A. Fid it by doing: yum install ncurses-devel

Q. error: redeclaration of C++ built-in type ‘bool’

A.make clean make distclean 清空编译缓存,重新编译

安装MYSQL时出现总是

Q :Error: Unknown character set: ‘gbk’ Errno.: 1115

A:这个是由于在编译MSYQL的时候没有 –with-xcharset=all  –with-extra-charsets=gb2312,gbk

安装PHP再现的总是

Q:configure: error: Cannot find MySQL header files under yes.

A:编译的时候指定mysql的路径 /usr/local/mysql

//重新编译

Q If configure fails try –with-jpeg-dir=<DIR>

configure: error: libpng.(a|so) not found.

If configure fails try –with-jpeg-dir=<DIR>

configure: error: libpng.(a|so) not found.

A 。安装libjpeg库

rpm -ivh libjpeg-devel-1.2.10-7.0.2.i386.rpm

Q. If configure fails try –with-jpeg-dir=<DIR>

configure: error: libpng.(a|so) not found.

A. 安装 libpng库

rpm -ivh libpng-devel-1.2.10-7.0.2.i386.rpm

Q. libtool: link: `ext/pdo_mysql/mysql_driver.lo’ is not a valid libtool object

A. 重新编译便可解决

Q. The mysql driver is not currently installed

A. 解决是没有安装pdo-mysql这个扩展了,重新配置,加上–with-pdo-mysql=/usr/local/mysql/

机器人 2008-4-13  18:27 于 北京

五种常见的 PHP 设计模式

Posted by 机器人 on 14th 一月 2008 in php/javascript

设计模式只是为 Java 架构师准备的 —— 至少您可能一直这样认为。实际上,设计模式对于每个人都非常有用。如果这些工具不是 “架构太空人” 的专利,那么它们又是什么?为什么说它们在 PHP 应用程序中非常有用?本文解释了这些问题。

设计模式不仅代表着更快开发健壮软件的有用方法,而且还提供了以友好的术语封装大型理念的方法。例如,您可以说您正在编写一个提供松散耦合的消息传递系统,也可以说你正在编写名称为观察者 的模式。

用较小的示例展示模式的价值是非常困难的。这往往有些大材小用的意味,因为模式实际上是在大型代码库中发挥作用的。本文不展示大型应用程序,所以您需要思索的是在您自己的大型应用程序中应用示例原理的方法 ——而不是本文演示的代码本身。这不是说您不应该在小应用程序中使用模式。很多良好的应用程序都以小应用程序为起点,逐渐发展到大型应用程序,所以没有理由不以此类扎实的编码实践为基础。

既然您已经了解了设计模式以及它们的有用之处,现在我们来看看 PHP5 的五种常用模式。

工厂模式

最初在设计模式 一书中,许多设计模式都鼓励使用松散耦合。要理解这个概念,让我们最好谈一下许多开发人员从事大型系统的艰苦历程。在更改一个代码片段时,就会发生问题,系统其他部分 —— 您曾认为完全不相关的部分中也有可能出现级联破坏。

该问题在于紧密耦合 。系统某个部分中的函数和类严重依赖于系统的其他部分中函数和类的行为和结构。您需要一组模式,使这些类能够相互通信,但不希望将它们紧密绑定在一起,以避免出现联锁。

在大型系统中,许多代码依赖于少数几个关键类。需要更改这些类时,可能会出现困难。例如,假设您有一个从文件读取的 User 类。您希望将其更改为从数据库读取的其他类,但是,所有的代码都引用从文件读取的原始类。这时候,使用工厂模式会很方便。

工厂模式 是一种类,它具有为您创建对象的某些方法。您可以使用工厂类创建对象,而不直接使用 new。这样,如果您想要更改所创建的对象类型,只需更改该工厂即可。使用该工厂的所有代码会自动更改。

清单 1 显示工厂类的一个示列。等式的服务器端包括两个部分:数据库和一组 PHP 页面,这些页面允许您添加反馈、请求反馈列表并获取与特定反馈相关的文章。

list1

 

interface IUser {
    function getName();
}
class User implements IUser {
    public function __construct( $id ) {

    }
    public function getName() {
        return "Jack";
    }
}
class UserFactory {
    public static function Create( $id ) {
        return new User( $id );
    }
}
$uo = UserFactory::Create( 1 );
echo( $uo->getName()."\n" );

IUser 接口定义用户对象应执行什么操作。IUser 的实现称为 User,UserFactory 工厂类则创建 IUser 对象。此关系可以用图 1 中的 UML 表示。

图 1. 工厂类及其相关 IUser 接口和用户类

如果您使用 php 解释器在命令行上运行此代码,将得到如下结果:

测试代码会向工厂请求 User 对象,并输出 getName 方法的结果。

% php factory1.php

Jack

%

有一种工厂模式的变体使用工厂方法。类中的这些公共静态方法构造该类型的对象。如果创建此类型的对象非常重要,此方法非常有用。例如,假设您需要先创建对象,然后设置许多属性。此版本的工厂模式会将该进程封装在单个位置中,这样,不用复制复杂的初始化代码,也不必将复制好的代码在在代码库中到处粘贴。

清单2.显示使用工厂方法的一个示例。

list2

 

interface IUser {
    function getName();
}
class User implements IUser {
    public static function Load( $id ) {
        return new User( $id );
    }
    public static function Create( ) {
        return new User( null );
    }
    public function __construct( $id ) {
    }
    public function getName() {
        return "Jack";
    }
}
$uo = User::Load( 1 );
echo( $uo->getName()."\n" );

这段代码要简单得多。它仅有一个接口 IUser 和一个实现此接口的 User 类。User 类有两个创建对象的静态方法。此关系可用图 2 中的 UML 表示。

图 2. IUser 接口和带有工厂方法的 user 类

在命令行中运行脚本产生的结果与清单 1 的结果相同,如下所示:

% php factory2.php

Jack

%

如上所述,有时此类模式在规模较小的环境中似乎有些大材小用。不过,最好还是学习这种扎实的编码形式,以便应用于任意规模的项目中。

单元素模式

某些应用程序资源是独占的,因为有且只有一个此类型的资源。例如,通过数据库句柄到数据库的连接是独占的。您希望在应用程序中共享数据库句柄,因为在保持连接打开或关闭时,它是一种开销,在获取单个页面的过程中更是如此。

单元素模式可以满足此要求。如果应用程序每次包含且仅包含一个对象,那么这个对象就是一个单元素(Singleton)。清单 3 中的代码显示了 PHP V5 中的一个数据库连接单元素。

 list3

require_once("DB.php");
class DatabaseConnection {
    private $_handle = null;
    public static function get() {
        static $db = null;
        if ($db == null)
        $db = new DatabaseConnection();
        return $db;
    }
    private function __construct() {
        $dsn = 'mysql://root:password@localhost/photos';
        $this->_handle =& DB::Connect( $dsn, array() );
    }
    public function handle() {
        return $this->_handle;
    }
}
print( "Handle = ".DatabaseConnection::get()->handle()."\n" );
print( "Handle = ".DatabaseConnection::get()->handle()."\n" );

此代码显示名为 DatabaseConnection 的单个类。您不能创建自已的 DatabaseConnection,因为构造函数是专用的。但使用静态 get 方法,您可以获得且仅获得一个 DatabaseConnection 对象。此代码的 UML 如图 3 所示。

图 3. 数据库连接单元素

在两次调用间,handle 方法返回的数据库句柄是相同的,这就是最好的证明。您可以在命令行中运行代码来观察这一点。

% php singleton.php

Handle = Object id #3

Handle = Object id #3

%

返回的两个句柄是同一对象。如果您在整个应用程序中使用数据库连接单元素,那么就可以在任何地方重用同一句柄。

您可以使用全局变量存储数据库句柄,但是,该方法仅适用于较小的应用程序。在较大的应用程序中,应避免使用全局变量,并使用对象和方法访问资源。

观察者模式

观察者模式为您提供了避免组件之间紧密耦合的另一种方法。该模式非常简单:一个对象通过添加一个方法(该方法允许另一个对象,即观察者 注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关。结果是对象可以相互对话,而不必了解原因。

一个简单示例是系统中的用户列表。清单 4 中的代码显示一个用户列表,添加用户时,它将发送出一条消息。添加用户时,通过发送消息的日志观察者可以观察此列表。

 list4

interface IObserver {
    function onChanged( $sender, $args );
}
interface IObservable    {
    function addObserver( $observer );
}

class UserList implements IObservable {
    private $_observers = array();
    public function addCustomer( $name ) {
        foreach( $this->_observers as $obs )
        $obs->onChanged( $this, $name );
    }

    public function addObserver( $observer ) {
        $this->_observers []= $observer;
    }
}

class UserListLogger implements IObserver {
    public function onChanged( $sender, $args ) {
        echo( "'$args' added to user list\n" );
    }
}
$ul = new UserList();
$ul->addObserver( new UserListLogger() );
$ul->addCustomer( "Jack" );

此代码定义四个元素:两个接口和两个类。IObservable 接口定义可以被观察的对象,UserList 实现该接口,以便将本身注册为可观察。IObserver 列表定义要通过怎样的方法才能成为观察者,UserListLogger 实现 IObserver 接口。图 4 的 UML 中展示了这些元素。

图 4. 可观察的用户列表和用户列表事件日志程序

如果在命令行中运行它,您将看到以下输出:

% php observer.php

‘Jack’ added to user list

%

测试代码创建 UserList,并将 UserListLogger 观察者添加到其中。然后添加一个消费者,并将这一更改通知 UserListLogger。

认识到 UserList 不知道日志程序将执行什么操作很关键。可能存在一个或多个执行其他操作的侦听程序。例如,您可能有一个向新用户发送消息的观察者,欢迎新用户使用该系统。这种方法的价值在于 UserList 忽略所有依赖它的对象,它主要关注在列表更改时维护用户列表并发送消息这一工作。

此模式不限于内存中的对象。它是在较大的应用程序中使用的数据库驱动的消息查询系统的基础。

命令链模式

命令链 模式以松散耦合主题为基础,发送消息、命令和请求,或通过一组处理程序发送任意内容。每个处理程序都会自行判断自己能否处理请求。如果可以,该请求被处理,进程停止。您可以为系统添加或移除处理程序,而不影响其他处理程序。清单 5 显示了此模式的一个示例。

 list5

interface ICommand {
    function onCommand( $name, $args );
}
class CommandChain {
    private $_commands = array();
    public function addCommand($cmd) {
        $this->_commands []= $cmd;
    }

    public function runCommand( $name, $args ) {
        foreach( $this->_commands as $cmd ) {
            if ($cmd->onCommand($name,$args))
                return;
        }
    }
}

class UserCommand implements ICommand {
public function onCommand($name,$args) {
    if ($name != 'addUser') return false;
        echo( "UserCommand handling 'addUser'\n" );
        return true;
    }
}
class MailCommand implements ICommand {
    public function onCommand( $name, $args) {
        if($name != 'mail') return false;
        echo( "MailCommand handling 'mail'\n" );
        return true;
    }
}
$cc = new CommandChain();
$cc->addCommand( new UserCommand() );
$cc->addCommand( new MailCommand() );
$cc->runCommand( 'addUser', null );
$cc->runCommand( 'mail', null );

此代码定义维护 ICommand 对象列表的 CommandChain 类。两个类都可以实现 ICommand 接口 —— 一个对邮件的请求作出响应,另一个对添加用户作出响应。图 5 给出了 UML。

图 5. 命令链及其相关命令

如果您运行包含某些测试代码的脚本,则会得到以下输出:

% php chain.php

UserCommand handling ‘addUser’

MailCommand handling ‘mail’

%

代码首先创建 CommandChain 对象,并为它添加两个命令对象的实例。然后运行两个命令以查看谁对这些命令作出了响应。如果命令的名称匹配 UserCommand 或 MailCommand,则代码失败,不发生任何操作。

为处理请求而创建可扩展的架构时,命令链模式很有价值,使用它可以解决许多问题。

策略模式

我们讲述的最后一个设计模式是策略模式。在此模式中,算法是从复杂类提取的,因而可以方便地替换。例如,如果要更改搜索引擎中排列页的方法,则策略模式是一个不错的选择。思考一下搜索引擎的几个部分 ——一部分遍历页面,一部分对每页排列,另一部分基于排列的结果排序。在复杂的示例中,这些部分都在同一个类中。通过使用策略模式,您可将排列部分放入另一个类中,以便更改页排列的方式,而不影响搜索引擎的其余代码。

作为一个较简单的示例,清单 6 显示了一个用户列表类,它提供了一个根据一组即插即用的策略查找一组用户的方法。

 list6

interface IStrategy {
    function filter( $record );
}
class FindAfterStrategy implements IStrategy {
    private $_name;
    public function __construct( $name ) {
        $this->_name = $name;
    }

    public function filter( $record ) {
        return strcmp( $this->_name, $record ) <= 0;
    }
}

class RandomStrategy implements IStrategy {
    public function filter( $record ) {
        return rand( 0, 1 ) >= 0.5;
    }
}

class UserList {
    private $_list = array();
    public function __construct( $names ) {
        if ( $names != null ) {
            foreach( $names as $name ) {
                $this->_list []= $name;
            }
        }
    }
    public function add( $name ) {
        $this->_list []= $name;
    }

    public function find( $filter ) {
        $recs = array();
        foreach($this->_list as $user) {
            if ($filter->filter($user))    $recs []= $user;
        }
        return $recs;
    }
}

$ul = new UserList( array( "Andy", "Jack", "Lori", "Megan" ) );
$f1 = $ul->find( new FindAfterStrategy( "J" ) );
print_r( $f1 );

$f2 = $ul->find( new RandomStrategy() );
print_r( $f2 );

      此代码的 UML 如图 6 所示。

图 6. 用户列表和用于选择用户的策略

UserList 类是打包名称数组的一个包装器。它实现 find 方法,该方法利用几个策略之一来选择这些名称的子集。这些策略由 IStrategy 接口定义,该接口有两个实现:一个随机选择用户,另一个根据指定名称选择其后的所有名称。运行测试代码时,将得到以下输出:

% php strategy.php

Array

(

[0] => Jack

[1] => Lori

[2] => Megan

)

Array

(

[0] => Andy

[1] => Megan

)

%

测试代码为两个策略运行同一用户列表,并显示结果。在第一种情况中,策略查找排列在 J 后的任何名称,所以您将得到 Jack、Lori 和 Megan。第二个策略随机选取名称,每次会产生不同的结果。在这种情况下,结果为 Andy 和 Megan。

策略模式非常适合复杂数据管理系统或数据处理系统,二者在数据筛选、搜索或处理的方式方面需要较高的灵活性。

机器人 2008-2-28 整理 于 北京

 

 

文件格式类(收藏)

Posted by 机器人 on 8th 十一月 2007 in php/javascript

文件格式类(收藏)

 

$mime_types = array(
    'gif' => 'image/gif',
    'jpg' => 'image/jpeg',
    'jpeg' => 'image/jpeg',
    'jpe' => 'image/jpeg',
    'bmp' => 'image/bmp',
    'png' => 'image/png',
    'tif' => 'image/tiff',
    'tiff' => 'image/tiff',
    'pict' => 'image/x-pict',
    'pic' => 'image/x-pict',
    'pct' => 'image/x-pict',
    'tif' => 'image/tiff',
    'tiff' => 'image/tiff',
    'psd' => 'image/x-photoshop', 

    'swf' => 'application/x-shockwave-flash',
    'js' => 'application/x-javascript',
    'pdf' => 'application/pdf',
    'ps' => 'application/postscript',
    'eps' => 'application/postscript',
    'ai' => 'application/postscript',
    'wmf' => 'application/x-msmetafile', 

    'css' => 'text/css',
    'htm' => 'text/html',
    'html' => 'text/html',
    'txt' => 'text/plain',
    'xml' => 'text/xml',
    'wml' => 'text/wml',
    'wbmp' => 'image/vnd.wap.wbmp', 

    'mid' => 'audio/midi',
    'wav' => 'audio/wav',
    'mp3' => 'audio/mpeg',
    'mp2' => 'audio/mpeg', 

    'avi' => 'video/x-msvideo',
    'mpeg' => 'video/mpeg',
    'mpg' => 'video/mpeg',
    'qt' => 'video/quicktime',
    'mov' => 'video/quicktime', 

    'lha' => 'application/x-lha',
    'lzh' => 'application/x-lha',
    'z' => 'application/x-compress',
    'gtar' => 'application/x-gtar',
    'gz' => 'application/x-gzip',
    'gzip' => 'application/x-gzip',
    'tgz' => 'application/x-gzip',
    'tar' => 'application/x-tar',
    'bz2' => 'application/bzip2',
    'zip' => 'application/zip',
    'arj' => 'application/x-arj',
    'rar' => 'application/x-rar-compressed', 

    'hqx' => 'application/mac-binhex40',
    'sit' => 'application/x-stuffit',
    'bin' => 'application/x-macbinary', 

    'uu' => 'text/x-uuencode',
    'uue' => 'text/x-uuencode', 

    'latex'=> 'application/x-latex',
    'ltx' => 'application/x-latex',
    'tcl' => 'application/x-tcl', 

    'pgp' => 'application/pgp',
    'asc' => 'application/pgp',
    'exe' => 'application/x-msdownload',
    'doc' => 'application/msword',
    'rtf' => 'application/rtf',
    'xls' => 'application/vnd.ms-excel',
    'ppt' => 'application/vnd.ms-powerpoint',
    'mdb' => 'application/x-msaccess',
    'wri' => 'application/x-mswrite',
);

机器人 2007-11-8 于 北京

 

php画饼状图

Posted by 机器人 on 22nd 九月 2007 in php/javascript

很多时候我们可能需要把一些数据使用图型的形式展现在用户面前,从而达到比较直观的效果。。。所以需采用程序来生成一些这样的图。。下面是从网上整理的一个例子。

运行执行效果如下:

   

 

代码如下:

 

<?php
    /**
     * @date 2007-9-21
     *
     */

    define("ANGLE_STEP", 5); //定义画椭圆弧时的角度步长
    define("FONT_USED", "./SURSONG.TTF"); // 使用到的字体文件位置

    function draw_getdarkcolor($img,$clr) //求$clr对应的暗色
    {
        $rgb = imagecolorsforindex($img,$clr);
        return array($rgb["red"]/2,$rgb["green"]/2,$rgb["blue"]/2);
    }

    function draw_getexy($a, $b, $d) //求角度$d对应的椭圆上的点坐标
    {
        $d = deg2rad($d);
        return array(round($a*Cos($d)), round($b*Sin($d)));
    }

    function draw_arc($img,$ox,$oy,$a,$b,$sd,$ed,$clr) //椭圆弧函数
    {
        $n = ceil(($ed-$sd)/ANGLE_STEP);
        $d = $sd;
        list($x0,$y0) = draw_getexy($a,$b,$d);
        for($i=0; $i<$n; $i++)
        {
            $d = ($d+ANGLE_STEP)>$ed?$ed:($d+ANGLE_STEP);
            list($x, $y) = draw_getexy($a, $b, $d);
            imageline($img, $x0+$ox, $y0+$oy, $x+$ox, $y+$oy, $clr);
            $x0 = $x;
            $y0 = $y;
        }
    }

    function draw_sector($img, $ox, $oy, $a, $b, $sd, $ed, $clr) //画扇面
    {
        $n = ceil(($ed-$sd)/ANGLE_STEP);
        $d = $sd;
        list($x0,$y0) = draw_getexy($a, $b, $d);
        imageline($img, $x0+$ox, $y0+$oy, $ox, $oy, $clr);
        for($i=0; $i<$n; $i++)
        {
            $d = ($d+ANGLE_STEP)>$ed?$ed:($d+ANGLE_STEP);
            list($x, $y) = draw_getexy($a, $b, $d);
            imageline($img, $x0+$ox, $y0+$oy, $x+$ox, $y+$oy, $clr);
            $x0 = $x;
            $y0 = $y;
        }
        imageline($img, $x0+$ox, $y0+$oy, $ox, $oy, $clr);
        list($x, $y) = draw_getexy($a/2, $b/2, ($d+$sd)/2);
        imagefill($img, $x+$ox, $y+$oy, $clr);
    }

    function draw_sector3d($img, $ox, $oy, $a, $b, $v, $sd, $ed, $clr) //3d扇面
    {
        draw_sector($img, $ox, $oy, $a, $b, $sd, $ed, $clr);
        if($sd<180)
        {
            list($R, $G, $B) = draw_getdarkcolor($img, $clr);
            $clr=imagecolorallocate($img, $R, $G, $B);
            if($ed>180) $ed = 180;
            list($sx, $sy) = draw_getexy($a,$b,$sd);
            $sx += $ox;
            $sy += $oy;
            list($ex, $ey) = draw_getexy($a, $b, $ed);
            $ex += $ox;
            $ey += $oy;
            imageline($img, $sx, $sy, $sx, $sy+$v, $clr);
            imageline($img, $ex, $ey, $ex, $ey+$v, $clr);
            draw_arc($img, $ox, $oy+$v, $a, $b, $sd, $ed, $clr);
            list($sx, $sy) = draw_getexy($a, $b, ($sd+$ed)/2);
            $sy += $oy+$v/2;
            $sx += $ox;
            imagefill($img, $sx, $sy, $clr);
        }
    }
    function draw_getindexcolor($img, $clr) //RBG转索引色

    {
        $R = ($clr>>16) & 0xff;
        $G = ($clr>>8)& 0xff;
        $B = ($clr) & 0xff;
        return imagecolorallocate($img, $R, $G, $B);
    }

    // 绘图主函数,并输出图片
    // $datLst 为数据数组, $labLst 为标签数组, $datLst 为颜色数组
    // 以上三个数组的维数应该相等
    function draw_img($datLst,$labLst,$clrLst,$a=250,$b=120,$v=20,$font=10)
    {
        $ox = 5+$a;
        $oy = 5+$b;
        $fw = imagefontwidth($font);
        $fh = imagefontheight($font);
        $n = count($datLst);//数据项个数

        $w = 10+$a*2; //图像宽度
        $h = 10+$b*2+$v+($fh+2)*$n;//图像高度

        $img = imagecreate($w, $h);

        //转RGB为索引色
        for($i=0; $i<$n; $i++)
            $clrLst[$i] = draw_getindexcolor($img,$clrLst[$i]);    

        $clrbk = imagecolorallocate($img, 0xff, 0xff, 0xff);
        $clrt = imagecolorallocate($img, 0x00, 0x00, 0x00);

        //填充背景色
        imagefill($img, 0, 0, $clrbk);

        //求和
        $tot = 0;
        for($i=0; $i<$n; $i++) $tot += $datLst[$i];
        $sd = 0;
        $ed = 0;
        $ly = 10+$b*2+$v;
        for($i=0; $i<$n; $i++)
        {
            $sd = $ed;
            $ed += $datLst[$i]/$tot*360; 

            //画圆饼
            draw_sector3d($img, $ox, $oy, $a, $b, $v, $sd, $ed, $clrLst[$i]);
            //画标签
            imagefilledrectangle($img, 5, $ly, 5+$fw, $ly+$fh, $clrLst[$i]);
            imagerectangle($img, 5, $ly, 5+$fw, $ly+$fh, $clrt);

            $str = iconv("GB2312", "UTF-8", $labLst[$i]);
            imagettftext($img, $font, 0, 5+2*$fw, $ly+13, $clrt, FONT_USED,
                $str.":".$datLst[$i]."(".(round(10000*($datLst[$i]/$tot))/100)."%)"
            );
            $ly += $fh+2;
        }

        //输出图形
        header("Content-type: image/jpeg");

        //输出生成的图片
        imagejpeg($img);
    }

    $datLst = array(30, 10, 20, 20, 10, 20, 10, 20); //数据
    $labLst = array("
        中国科技大学",
        "安徽理工大学",
        "清华大学",
        "北京大学",
        "南京大学",
        "上海大学",
        "河海大学",
        "中山大学"
    ); //标签
    $clrLst = array(0x99ff00, 0xff6666, 0x0099ff, 0xff99ff, 0xffff99, 0x99ffff, 0xff3333, 0x009999);

    //画图
    draw_img($datLst,$labLst,$clrLst);
?>

机器人 2007-9-21 整理 于 北京

 

php入门尝试视频

Posted by 机器人 on 1st 八月 2007 in phpoo

介绍:

本视频主要是向大家演示了php创建一个简单注册登录系统基本的过程,从客户端到服务器端一步一步的进行引导,通过本视频的学习,大家能基本分清网站和php的关系,php在网站中充当一个什么样的角色,对所谓的客户端和服务器端究竟是一个什么样的关系等对初学者来说容易搞混的问题.

录制日期:2007-7-10

php入门尝试视频(一)

全屏播放

 php入门尝试视频(二)

全屏播放

php入门尝试视频(三)

全屏播放

php入门尝试视频(四)

全屏播放

php配置详解视频

Posted by 机器人 on 29th 七月 2007 in phpoo

一直都没有把视频发到网上来.今天把比较小的传到了土豆网.不过被处理后失桢比较严重,不过也能凑合看.

这些视频都是我们phpoo成员的杰作,我们在每个分享日(每周五)都会进行相关专题讨论,这些比较有价值的过程我们都将通过视频来保存,这也为为我们phpoo成员的一段美好的回忆.当然,这一切我们很乐意和朋友们一起分享.

这些只是一部分,以后慢慢发上来.

标题:php配置详解视频

phpoo配置全过程讲解,对有些细节部分加了特别的说明:

录制日期:2007-7-7

全屏浏览

2007年7月29日 机器人 于 北京

 

PHP日常使用小tips

Posted by 机器人 on 15th 六月 2007 in php/javascript

1.简易判断ip地址合法性

2.email的正则判断

3.检测ip地址和mask是否合法的例子

1.简易判断ip地址合法性

if(!strcmp(long2ip(sprintf("%u",ip2long($ip))),$ip)) echo "is ip\n";

—-

2.email的正则判断

eregi("^[_\.0-9a-zA-Z-]+@([0-9a-zA-Z][0-9a-zA-Z_-]+\.)+[a-zA-Z]{2,6}$", $email);

—-

3.检测ip地址和mask是否合法的例子

$ip = ’192.168.0.84′;

$mask = ’255.255.255.0′;

$network = ’192.168.0′;

$ip = ip2long($ip);

$mask = ip2long($mask);

$network = ip2long($network);

if( ($ip & $mask) == $network) echo "valid ip and mask\n";

?>

—-

4.今天解决了一个巨郁闷的问题

ipb的添加用户页面toadduser.php似乎会重复提交,导致在添加新用户的时候总是报该用户已经存在…已经郁闷了我3天了,终于搞定,大快人心!

—-

5.关于表单刷新

问:为什么我在点击浏览器的后退按钮后,所有字段的信息都被清空了?

答:这是由于你在你的表单提交页面中使用了 session_start 函数。该函数会强制当前页面不被缓存。解决办法为,在你的 Session_start 函数后加入 header("Cache-control: private"); 注意在本行之前你的PHP程序不能有任何输出。

补充:还有基于session的解决方法,在session_start前加上

session_cache_limiter(‘nocache’);// 清空表单

session_cache_limiter(‘private’); //不清空表单,只在session生效期间

session_cache_limiter(‘public’); //不清空表单,如同没使用session一般

可以在session_start();前加上    session_cache_limiter("private,max-age=10800");

摘自phpe.net

—-

6.快速搞定文件下载头部输出

header("Content-type: application/x-download");

header("Content-Disposition: attachment; filename=$file_download_name;");

header("Accept-Ranges: bytes");

header("Content-Length: $download_size");

echo ‘xxx’

…….2004-08-19 11:50:30

—-

7.用header输出ftp下载方式,并且支持断点续传

一个例子:

header(‘Pragma: public’);

header(‘Cache-Control: private’);

header(‘Cache-Control: no-cache, must-revalidate’);

header(‘Accept-Ranges: bytes’);

header(‘Connection: close’);

header("Content-Type: audio/mpeg");

header("Location:ftp://download:1bk3l4s3k9s2@218.30.116.103/1001/咖哩辣椒/咖喱辣椒.rmvb");

…….2004-10-08 13:26:45

—-

8. 时间处理集锦

1.善用strtotime()

strtotime(‘now’);

strtotime(‘+1 day’);

strtotime(‘-3 hour’);