十二/085
php和python的比较
python的应用现在越来越多了,想多了解点pygtk和django的东西,但只有一些php和C的基础,而python的语法还是比较独特的。接触python半年多,总结一点和php的比较以及优缺点。
首先,python的性能一直比较争议,而php本身的速度是比java的东西慢,但和db操作起来,肯定是比java的东西快很多了,这算是一个php的优势。并且php的成本较低(LAMP)应该算是很便宜的东东了,而现在支持python的服务器还不是很普遍,对机器要求也较高。下面简单看看语法。
php这种类C的语法是以大括号划分代码块来确定程序逻辑的,而python则是以代码缩进的形式。优缺点都有,缩进自然简化了输入繁琐,有人描述写python程序跟写英文作文一样,虽然这个描述有点夸张,但确实反应了python的优雅语法。唯一比较麻烦的事情就是用惯了类C语法的人对缩进不是很适应,比如我刚用python的时候,程序报错30%是缩进相关的问题,慢慢习惯就好了。下面说说引号,php中有单引和双引,加上dochere语法。单引不解析其内的变量或者转义字符,但是速度较快,所以如果是纯字符串,推荐用单引。而双引会将里面的变量或者转义字符解析后输出。php的dochere语法可以输入较长的字符串,而不用顾及单引和双引的交叉问题,但dochere语法要求较为“严格”,比如必须顶头写,开始标记和结束标记必须相同。而python的三引号语法使用起来很简单,单引和双引则没有区别(这点跟php和java等语言不一样)。
下面看数据类型。别的区别不大,主要是php数组这块,php如果分的比较详细,就是一个数组和关联数组,数组相当于python的列表(list),关联数组相当于python的字典(dictionary, perl中叫哈希hash),另外python还有一个tuple(元组),其中的内容和字符串一样是不可变化的。下面看数据处理,php的大部分数据处理都是数组操作,有一大堆以array_开头的函数可提供功能,数组没有负索引,而python的序列相关操作比较方便,功能更强大。php在一些特殊操作平台用-a参数可以使用交互模式,而python也支持交互模式,一些简单计算可以直接使用。
web方面:php的开发框架比较成熟,大都是mysql数据库驱动的。而python目前比较成熟的开发框架不是很多,流行的有zope,django和豆瓣用的Quixote。也不知道豆瓣当时为什么选择后者,可能当时ror和django这些东西还没有吧。
最后说下OO,现在大部分php的产品还是面向过程的,除了使用一些第三方的开源库。php5引入了很多的面向对象特性,对之前的版本来说,面向对象特性就是个鸡肋。而python的模块,OO机制很不错,也是学习的一个重点。
总之,python的特性有很多,学习它一定不会失望。由于本人水平有限的可怜,这个小文章就当是给想接触python的phper们一点动力吧。
十/080
PHP Architect’s Guide to PHP Security [2]
White List Validation (白名单验证)
Being Careful with File Uploads (文件上传时要小心)
File Content Validation (文件内容验证)
Accessing Uploaded Data (访问上传数据)
The Dangers of Magic Quotes (Magic Quotes的危险性)
Magic Quotes Normalization (Magic Quotes正规化)
Validating Serialized Data (验证序列化数据)
External Resource Validation (外部资源验证)
Assumption is the enemy of security and making assumptions about user input is a sure way to allow an attacker to subvert your code. 又一次强调开发者的假设所带来的后果。对开发者来说,普遍假设selection box和check box以及radio button和hidden字段值是不用验证的,这就完全错了,
因为恶意用户可以拷贝html表单代码并且修改后来进行恶意提交任意数据。比起黑名单的概念,我们最好还是选择白名单,也就是说我们给出合法的值,然后验证是否合法;而不是给出不合法的值,验证值是否非法。显然后者不如前者来得安全。这里作者给出一个例子,说明了这个问题:
$months = array(“January”, “February”, /* … */);
if (empty($_POST[‘month’]) || !in_array($_POST[‘month’], $months)) {
exit(“Quit hacking, you’re not a lumberjack!”);
}
关于文件上传:如果你的应用程序不会使用到文件上传的特性,你可以编辑php.ini文件来禁止文件上传。
file_uploads=off
upload_max_filesize指令可以控制上传的单个文件最大值,以字节为单位。默认值为2M
post_max_size指令限制了当表单以POST方式提交的数据大小。通常情况下,这个值我们应该设置地比上面那个file_uploads稍微大一点点。如果你可能用到多文件上传,根据需要自行调整。默认值为8M。
(待补充。。。)
九/087
PHP Architect’s Guide to PHP Security [1]
这几天稍微轻松点,就再看了一次PHP Architect’s Guide to PHP Security这本经典PHP安全书籍。其中整理了一些笔记之类的东西,分享给大家。都是个人组织和翻译的东西,如果有不周到的地方还请广大安全爱好者给出批评和指正。本来想逐字翻译全文,但是这是一个浩大的工程,并且学习意义不大,所以挑选一些重要的内容进行翻译和注释。


前言和介绍就略过不翻译了,作者描述了一下PHP安全的重要性,以及为何变得如此重要。我想目前线上的很多php站点遭到攻击和破坏足以说明这点了,我们直接来看第一章Input Validation。今天先写前半章吧。(一章内容太多,本人英文比较菜,看完需要差不多3个小时)
九/082
php抓取页面技巧
都知道用php抓取网页文件要用到正则表达式preg_match_all和file_get_contents函数,后者用来获取文件内容,前者用来过滤出需要的内容。
昨天抓取一个页面的时候,发现了一个有点bt的页面。里面的标点符号都替换成了图片,就是为了防止批量复制粘贴,因为这样粘贴进来的文章没有标点符号可想而知有多痛苦了。不过难不倒我们。
虽然每个文章的标点符号是用程序随即生成图片名称的,也就是说每个图片的名字都不一样,但我们可以肯定同样的标点符号(比如逗号)图片的md5值肯定是一样的,可以测试下:
<?php
copy(‘http://www.target.com/article1/comma54321.gif’, ‘pic1.gif ‘);
copy(‘http://www.target.com/article2/comma12345.gif’, ‘pic2.gif’);
echo md5_file(‘pic1.gif’), ‘<br />’, md5_file(‘pic2.gif’);
?>
可以看出不同文章里面的相同标点符号图片md5值是一样的,这样我们就可以在抓取程序中定义一个数组,用来做替换。
<?php
$replace_into = array(
‘md5_1′ => ‘,’,
‘md5_2′ => ‘。’,
‘md5_3′ => ‘、’,
);
if (array_key_exists(md5_file(‘url’), $replace_into)) {
// do replacing str…
}
?>
这样抓取出来的东西则把图片替换为了我们想要的中文标点符号。问题解决。
此外,碰到一些有规则的图片,我们可以利用seq和shell知识做出一个下载器,下载下来进行分析。
#!/bin/bash
for i in `seq -w 1 100` do
wget -c "http://www.target.com/images/file_$i.gif"
done
四/080
使用memcache来存储PHP session
PHP的session数据大都是存储在DB上的,但是可以直接用 memcache 来作 PHP 的 session.save_handler,从而提高效率。
1. 安装 memcached。
2. 在 php.ini 中设置:
session.save_handler = memcache session.save_path = "tcp://127.0.0.1:11211"
或者某个目录下的 .htaccess :
php_value session.save_handler "memcache" php_value session.save_path "tcp://127.0.0.1:11211"
再或者在某个一个应用中:
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "tcp://127.0.0.1:11211");
使用多个 memcached server 时用逗号”,”隔开,并且和 Memcache::addServer() 文档中说明的一样,可以带额外的参数”persistent”、”weight”、”timeout”、”retry_interval” 等等,类似这样的:”tcp://host1:port1?persistent=1&weight=2,tcp://host2:port2″ 。
3. 启动 memcached:
memcached -d -l 127.0.0.1 -p 11212 -m 128
4. 在程序中使用 memcache 来作 session 存储,用例子测试一下:
<?php
session_start();
if (!isset($_SESSION['TEST'])) {
$_SESSION['TEST'] = time();
}
$_SESSION['TEST3'] = time();
print $_SESSION['TEST'];
print "<br><br>";
print $_SESSION['TEST3'];
print "<br><br>";
print session_id();
?>
5. 用 sessionid 去 memcached 里查询一下:
<?php
$memcache = memcache_connect('localhost', 11211);
var_dump($memcache->get('19216821213c65cedec65b0883238c278eeb573e077'));
?>
会有看到
string(37) "TEST|i:1177556731;TEST3|i:1177556881;"
这样的输出,证明 session 正常工作。
用 memcache 来存储 session 在读写速度上会比 files 时快很多,而且在多个服务器需要共用 session 时会比较方便,将这些服务器都配置成使用同一组 memcached 服务器就可以,减少了额外的工作量。缺点是 session 数据都保存在 memory 中,持久化方面有所欠缺,但对 session 数据来说也不是很大的问题。
另外,WS Memcached Session Handler for PHP 提供一种用 session_set_save_handler 来利用 memcached 的方法。