分类目录归档:PHP

PHP源码,PHP扩展,PHP程序

使用VC6.0生成VLD扩展

使用VC6.0生成VLD扩展

最近想看看PHP生成的源码是啥样子,于是google半天,终于完成。
环境:VC6.0
源码:php5.2.9源码包(可以去http://www.php.net/下载),解压,我的是解压在D盘根目录下。
Vld源码包(可以去http://pecl.php.net/package/vld/0.9.1下载),解压

生成过程如下:
1、在Windows平台启动 VC++ 6.0, 【文件】(File)->【新建】(New), 在 【工程】(Project)中选择 【Win32 Dynamic-Link Library】, 填写上 【工程名称】(Project Name) 和 【位置】(Location),如图1所示:

图1

图1

2、点击确定后,在第二屏选中 【一个空的DLL工程】(An empty DLL project), 点 【完成】Finish, 完成创建。此时会可能会弹出一个信息框,点击确定。

3、把解压后的vld源码中的vld文件夹下面的所有文件拷贝到到工程所在的目录(D:\php-5.2.9\ext\vld);

4、选择左侧的【Source Files】,点击右键,选择【添加文件到目录】,将D:\php-5.2.9\ext\vld目录下的所有C文件添加到此目录,如图2所示;

图2

图2

5、同样选择【Header Files】,添加所有的头文件到目录。如图3所示:

图3

图3

6、修改工程设置,选择【工程】(Project)->【设置】(Settings)->【C/C++】,在【工程选项】(Project Options:)的 最后加上 /Tc,在预处理程序定义中添加如下宏定义:ZEND_DEBUG=0,COMPILE_DL_VLD,ZTS=1,ZEND_WIN32,PHP_WIN32,HAVE_VLD=1

如果你需要编译其它扩展,请将COMPILE_DL_VLD 和 HAVE_VLD=1,后面的 “VLD” 改成和你要创建的工程名一致。

如图4所示:

 

图4

图4

7、选择【连接】(Link),在【对象/库模块】(Object/library modules)添加php5ts.lib,注意要以空格格开;

8、选择【工具】(Tools)->【选项】(Options)->【目录】(Directories),

在 【目录】(Show directories for:) 下拉框中选择 “Library files”,在 【路径】(Directories) 中添加 D:\php-5.2.9 (即 php5ts.lib 所在目录);如图5所示:

在【目录】(Show directories for:) 下拉框中选择 “Include files”

在【路径】(Directories)中添加 D:\PHP-5.2.9 (即 ext、regex、win32 所在目录)

在【路径】(Directories)中添加 D:\PHP-5.2.9\MAIN

在【路径】(Directories)中添加D:\PHP-5.2.9\ZEND

在【路径】(Directories)中添加 D:\PHP-5.2.9\TSRM

如图6所示: 

 

图5

图5

 

 

图6

图6

9、选择【组建】->【编译】,此时可能会出现报错。

php_vld.h文件的59行存在三个莫名其妙的点,将他们去掉就可以了。

10、选择【组建】->【组建】。成功!

在扩展下的Debug目录D:\php-5.2.9\ext\vld\Debug下有一个生成的dll文件。这就是我们所要的东东了!

 

暗黑破坏神

[问题描述]
无聊中的小x玩起了Diablo I… 游戏的主人公有n个魔法每个魔法分为若干个等级,第i个魔法有p[i]个等级(不包括0)。每个魔法的每个等级都有一个效果值,一个j级的i种魔法的效果值为w[i][j] 。魔法升一级需要一本相应的魔法书购买魔法书需要金币,第i个魔法的魔法书价格为c[i],而小x只有m个金币(好孩子不用修改器),你的任务就是帮助小x决定如何购买魔法书才能使所有魔法的效果值之和最大,开始时所有魔法为0级 效果值为0

Input
第一行 用空格隔开的两个整数n m ,以下n行 描述n个魔法,第i+1行描述 第i个魔法 格式如下 :c[i] p[i] w[i][1] w[i][2] … w[i][p[i]]

Output
第一行输出一个整数,即最大效果值。 以后n行输出你的方案:
第i+1行有一个整数v[i] 表示你决定把第i个魔法学到v[i]级
如果有多解 输出花费金币最少的一组
如果还多解 输出任意一组

Sample Input
3 10
1 3 1 2 2
2 3 2 4 6
3 3 2 1 10

Sample Output
11
1
0
3

Hint

数据范围:
0 < n <= 100 0 < m <= 500 0 < p[i] <= 50 0 < c[i] <= 10 算法描述:动态规划。 F[i][j] 表示前i个魔法使用j个金币可以达到的最大的效果。 状态转移方程: f[i][j] = max(f[i – 1][j], f[i – 1][j – k * c[i]] + w[i][k]) 1 <= k <= p[i] 并且j >= k * c[i]
对于第i个魔法,它可以不升级(也就是保持0级),同样也可以达到1到p[i]的级。然而要达到第k级的魔法,所要消耗的金币数是k*c[i],而金币数为j,所以状态转移方程就如上所示。最后还要使用一个二维数组存取这个最大值的时候这个魔法所要达到的级数。为后面的级数输出做准备。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdio.h>
#include <string.h>
#define max(a,b) a>b?a:b
int f[101][501], mark[101][501], p[101],  c[101], w[101][51], v[101];
int main()
{
	int n, m, i, j, k, max, t;
	scanf("%d%d", &n, &m);
	for (i = 1; i <= n; i++)
	{
		scanf("%d%d", &c[i], &p[i]);
		for (j = 1; j <= p[i]; j++)
			scanf("%d", &w[i][j]);
	}
	memset(f, 0, sizeof(f));
	for (i = 1; i <= n; i++) //对于每个魔法
	{
		for (j = 1; j <= m; j++)//当使用j个金币时
		{
			f[i][j] = f[i - 1][j];//不升级
			mark[i][j] = 0;//记录标记
			for (k = 1; k <= p[i]; k++)//对于每个级数
			{
				if (j >= k * c[i])//如果金币够用的话
				{
					if (f[i - 1][j - k * c[i]] + w[i][k] > f[i][j])//寻找最大的效果,并记录下来
					{
						f[i][j] = f[i - 1][j - k * c[i]] + w[i][k];
						mark[i][j] = k;
					}
				}
				else
					break;
			}
		}
	}
	max = 0;
	for (j = m; j >= 1; j--)//寻找花费金币最少,而效果最大的那个解
	{
		for (i = n; i >= 1; i--)
		{
			if (f[i][j] >= max)
			{
				k = j;
				t = i;
				max = f[i][j];
			}
		}
	}
	memset(v, 0, sizeof(v));
	j = k;//从后往前找出每个魔法所要达到的级数。
	for (i = t; i >= 1; i--)
	{
		v[i] = mark[i][j];
		j = j - c[i] * v[i];
	}
	printf("%d\n", max);
	for (i = 1; i <= n; i++)
		printf("%d\n", v[i]);
	return 0;
}

让Apache的URL rewrite支持post数据

    今天要做项目升级,但是由于之前的某些原因,所有的代码都被重写了,而且新的代码在原有系统的/sub/目录已经试运行几个月了,有部分的地址已经被其它网站调用(包括GET方式和POST方式)。于是就得保证在根目录和/sub/目录都必须指向根目录。于是,就有了apache rewrite。

    在切换之前测试目录指向是否有效,配置RewriteRule ^/sub/(.*)$ /$1 [R=301]

    GET方式没有问题,但是post的数据无法接收。

    Google半天,没有找到原因,只有看官方文档,一个一个参数的去试,所幸,才试了两个就可以了,只要在最后添加【P】,即强制使用代理转发,配置:RewriteRule ^/sub/(.*)$ /$1 [R=301,P]。

 
【结论】
    Apache的URL Rewrite可以支持post数据,但是必须设置P,

 
【建议】
    对于R标志,建议加上R=301,表示永久性跳转,对于SEO会好一些!

【Apache mod_rewrite规则重写的标志一览】
R[=code](force redirect) 强制外部重定向

强制在替代字符串加上http://thishost[:thisport]/前缀重定向到外部的URL.如果code不指定,将用缺省的302 HTTP状态码。

F(force URL to be forbidden)禁用URL,返回403HTTP状态码。

G(force URL to be gone) 强制URL为GONE,返回410HTTP状态码。

P(force proxy) 强制使用代理转发。

L(last rule) 表明当前规则是最后一条规则,停止分析以后规则的重写。

N(next round) 重新从第一条规则开始运行重写过程。

C(chained with next rule) 与下一条规则关联

如果规则匹配则正常处理,该标志无效,如果不匹配,那么下面所有关联的规则都跳过。

T=MIME-type(force MIME type) 强制MIME类型

NS (used only if no internal sub-request) 只用于不是内部子请求

NC(no case) 不区分大小写

QSA(query string append) 追加请求字符串

NE(no URI escaping of output) 不在输出转义特殊字符

例如:RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE] 将能正确的将/foo/zoo转换成/bar?arg=P1=zed

PT(pass through to next handler) 传递给下一个处理

例如:

RewriteRule ^/abc(.*) /def$1 [PT] # 将会交给/def规则处理

Alias /def /ghi

S=num(skip next rule(s)) 跳过num条规则

E=VAR:VAL(set environment variable) 设置环境变量

 

使用mod_rewrite时常用的服务器变量:

HTTP headers:HTTP_USER_AGENT, HTTP_REFERER, HTTP_COOKIE, HTTP_HOST, HTTP_ACCEPT

connection & request: REMOTE_ADDR, QUERY_STRING

server internals: DOCUMENT_ROOT, SERVER_PORT, SERVER_PROTOCOL

system stuff: TIME_YEAR, TIME_MON, TIME_DAY

 

RewriteRule规则表达式的说明:

    . 匹配任何单字符

    [chars] 匹配字符串:chars

    [^chars] 不匹配字符串:chars

    text1|text2 可选择的字符串:text1或text2

    ? 匹配0到1个字符

    * 匹配0到多个字符

    + 匹配1到多个字符

    ^ 字符串开始标志

    $ 字符串结束标志

    \n 转义符标志

 

反向引用 $N 用于 RewriteRule 中匹配的变量调用(0 <= N <= 9)

反向引用 %N 用于 RewriteCond 中最后一个匹配的变量调用(1 <= N <= 9)

 

RewriteCond适用的标志符

‘nocase|NC’ (no case)忽略大小

‘ornext|OR’ (or next condition)逻辑或,可以同时匹配多个RewriteCond条件

 

RewriteRule适用的标志符

‘redirect|R [=code]’ (force redirect)强迫重写为基于http开头的外部转向(注意URL的变化) 如:[R=301,L]

‘forbidden|F’ (force URL to be forbidden)重写为禁止访问

‘proxy|P’ (force proxy)重写为通过代理访问的http路径

‘last|L’ (last rule)最后的重写规则标志,如果匹配,不再执行以后的规则

‘next|N’ (next round)循环同一个规则,直到不能满足匹配

‘chain|C’ (chained with next rule)如果匹配该规则,则继续下面的有Chain标志的规则。

‘type|T=MIME-type’ (force MIME type)指定MIME类型

‘nosubreq|NS’ (used only if no internal sub-request)如果是内部子请求则跳过

‘nocase|NC’ (no case)忽略大小

‘qsappend|QSA’ (query string append)附加查询字符串

‘noescape|NE’ (no URI escaping of output)禁止URL中的字符自动转义成%[0-9]+的形式。

‘passthrough|PT’ (pass through to next handler)将重写结果运用于mod_alias

‘skip|S=num’ (skip next rule(s))跳过下面几个规则

‘env|E=VAR:VAL’ (set environment variable)添加环境变量