恩,python中一般会把调试代码跟普通代码混在一块
class xx:
# .....
if __name__ == '__main__':
testxx = xx()
#测试代码.... Copy Code
这个__name__ == ‘__main__’判断此文件是否被直接执行,而不是被其他文件import,所以在vim中调试时可以直接输入:!python % 执行当前正在编辑的文件,调试代码便会执行并输出结果
php也可以这么加调试代码,php中是这么实现的
class xx {
// ......
}
//确定当前被执行的文件就是自己,而不是被其他php文件包含
if (realpath($_SERVER['SCRIPT_FILENAME']) == __FILE__)
{
$testxx = new xx;
//测试代码....
} Copy Code
如果仅限在命令行运行测试代码就再加个条件
if (php_sapi_name() == 'cli' && realpath($_SERVER['SCRIPT_FILENAME']) == __FILE__)
Copy Code
为了更速度,vim配置里添加了一个快捷键F5
"php和python调试快捷键
au FileType php map <F5> :call DebugRun('php')<cr>
au FileType php imap <F5> <Esc>:call DebugRun('php')<cr>
au FileType python map <F5> :call DebugRun('python')<cr>
au FileType python imap <F5> <Esc>:call DebugRun('python')<cr>
function DebugRun(cmd)
:w
execute '!' . a:cmd . ' %'
endfunction Copy Code
OK,写完调试代码按下F5立刻有结果。
———–
post by gmail~
//前面插入操作省略...
$rt = mysql_insert_id();
var_dump($rt);
$rt = $this->DB->query("select last_insert_id() from yl_contact");
var_dump($rt);
//结果
//
//int(10000672)
//int(15476) Copy Code
10000672这个结果是准确的,15476是索引总量,也就是说这个表里的自增字段有一段是空的,但是有影响吗?
为什么mysql_insert_id()这个函数这么靠普呢? 因为它直接返回了上次插入返回结果里的insert_id
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql)
{
return mysql->last_used_con->insert_id;
} Copy Code
还是没弄明白为什么,求解~
———–
post by gmail~
搞webservice最痛苦的莫过于提供wsdl,前两天找到一个叫”PHP WSDL Generator”的工具,可以根据注释生成wsdl,刚开始写了一个测试类还行,后来发现问题多多,文件里有require一类引用外部文件时会出问题,写同样的注释有的函数可以正确的生成,有的函数却不行。这种深不可测的东西不用也罢,自己写了一个。虽然功能弱点,但是不会无厘头。
下载:http://code-of-emptyhua.googlecode.com/svn/trunk/php2wsdl.py
命令行的话这样:
#参数依次为 命名空间 提供服务的PHP的类名 soap访问地址 本地的PHP文件 生成wsd的保存地址
php2wsdl.py "Ox-Service" "SomeClass" "http://test.com/soapserver.php" ./SomeClass.php ./service.wsdl
Copy Code
图简单,这个脚本生成的wsdl会把array类型当成anyType,实际用的时候没有什么问题~
—————————————————————————
另:
打包上传比较麻烦,以后就用google code传东西了,也比较好管理
跟上面一块传的还有一段汉字转拼音的python脚本:http://code-of-emptyhua.googlecode.com/svn/trunk/hz2py,写这个脚本因为最近想注个好点的com域名,但是差来查去都被注册,难道好记点的域名真的光了吗。。于是从一个分词字典里生成了一个快5万个域名的txt,跑了一个whois脚本,最后结果没有注册只有不到300个,而且基本都是多音字。。只能叹生不逢时~
做web这么长时间,感觉最恶心的就是表单验证这块了,很无聊,很烦琐,也很重要..
这个验证类的功能参考了codeigniter的表单验证库的功能,按照我的想法实现完毕又去对照codeigniter的代码,感觉还是我的这个比较灵活实用
…
/**
* 表单验证类
* Author : emptyhua@gmail.com
* Version : beta
*/
class FormValidator
{
//所有验证函数定义时的前缀
const PREFIX = 'form_validator_';
//存储验证函数的出错信息
public static $error_messages = array();
//存储验证相关的数据
protected $valid_rules = array();
//存储上次验证的出错信息
protected $errors = array();
//是否完全检查
protected $complete_check = true;
public static function set_error($rule, $error)
{
self::$error_messages[$rule] = $error;
}
/**
* 遇到第一个错误便返回
*/
public function first_error_only()
{
$this->complete_check = false;
}
/**
* 执行所有验证规则,收集所有错误
*/
public function show_all_errors()
{
$this->complete_check = true;
}
/**
* 设置验证规则
* @param string $var 验证的变量名,例如 username
* @param string $var_name 变量名的描述,例如 用户名
* @param string $func_name 验证规则,可以是多个,并且可以传参,例如 require|length(9,12)
* @param string $error_message 自定义的出错信息,可选,如果给定将覆盖验证函数的默认出错信息
*/
public function set_rules($var, $var_name, $func_name, $error_message = NULL)
{
$data = array();
$data['var_name'] = $var_name;
$data['error'] = $error_message;
$data['funcs'] = array();
$funcs_with_arg = explode('|', $func_name);
$args_match = array();
//解析验证规则
foreach( $funcs_with_arg as $func_with_arg )
{
preg_match('/\((.*)\)$/', $func_with_arg, $args_match);
//规则函数是否携带参数
if ( count($args_match) > 0 )
{
//参数列表
$args = explode(',', $args_match[1]);
//去掉参数后的验证规则名
$func = str_replace('(' . $args_match[1] . ')', '', $func_with_arg);
$data['funcs'][$func] = $args;
}
else
{
$data['funcs'][$func_with_arg] = NULL;
}
}
$this->valid_rules[$var] = $data;
}
/**
* 检验一组数据是否合法
* @param array $data 一个关联数组
* @return boolean
*/
public function is_valid($data)
{
$this->errors = array();
$valid = true;
//遍历的顺序为规则添加的顺序
foreach( $this->valid_rules as $var => $rule )
{
//判断数据中是否有此字段,没有的话置一个空的
if (!isset($data[$var]))
$data[$var] = '';
foreach($rule['funcs'] as $func => $args)
{
//真实的验证函数的名称,例如 form_validator_require
$func_run = self::PREFIX . $func;
//如果函数未定义,循环继续
if ( !is_callable($func_run) ) continue;
//为验证函数组装参数
//顺序为:当前验证字段的值, 所有验证数据, 验证规则参数1, ...
if ( $args === NULL )
{
$args = array($data[$var], $data);
}
else
{
array_unshift($args, $data);
array_unshift($args, $data[$var]);
}
//调用验证函数
if ( !call_user_func_array($func_run, $args) )
{
$valid = false;
//如果set_rules的时候没有自定义错误信息,则使用默认出错信息
if ( $rule['error'] === NULL )
{
//使用sprintf拼接错误信息
//参数顺序: 验证字段的描述, 验证函数的参数1, 验证函数的参数2 ...
//去掉刚才添加的字段值
array_shift($args);
//去掉刚才添加的所有验证数据
array_shift($args);
//添加字段名的描述
array_unshift($args, $rule['var_name']);
//添加默认的出错信息
array_unshift($args, self::$error_messages[$func]);
$this->errors[] = call_user_func_array('sprintf', $args);
}
else
{
//使用自定义错误信息
$this->errors[] = $rule['error'];
continue 2;
}
//如果设置不进行完全检查,则发现第一个错误后跳出最外层循环
if ( !$this->complete_check )
{
break 2;
}
}
}
}
return $valid;
}
/**
* 获取出错信息
* @return string array
*/
public function get_errors()
{
return $this->errors;
}
/**
* 返回第一条出错信息
* @return string
*/
public function get_first_error()
{
return $this->errors[0];
}
}
//扩展验证规则很方便~
//设置规则的默认出错信息
FormValidator::set_error('require', '%s不能为空');
//定义验证函数,以FormValidator::PREFIX打头
function form_validator_require($str)
{
return !(trim($str) == '');
}
FormValidator::set_error('equal', '重复输入不一致');
function form_validator_equal($str, $data, $eqto)
{
if ( !isset($data[$eqto]) )
{
return false;
}
return $data[$eqto] == $str;
} Copy Code
使用方法
$vd = new FormValidator();
$vd->set_rules('p', '密码', 'require|length(9,12)');
$vd->set_rules('p2', '密码验证', 'equa(p)', '两次密码输入不一致');
if (!$vd->is_valid($_POST))
{
var_dump($vd->get_errors());
} Copy Code
今天把一直本地测试的php程序放到外网的机器跑(64位系统),没想到一个纯算数值的算法竟然得到不一样的结果,最后锁定在一个求模的操作上:$i % 4, $i在本地和server上打印出来都是434807526976, 但是求出来的结果却不一样~
原因是:
php的整型最大值为2147483647(32位系统上), 当数值赋值超过这个最大值时,变量便自动成为浮点型. 所以虽然打印出来一样,但本地打印的是一个是浮点型的$i,而server上是64位系统,整型最大值达到9223372036854775807 …. $i依然是一个整型.
取模运算的结果不一样是因为php在对数值取模运算时会把浮点数转换为整型再取模(这点就不如js了,js是可以对浮点取模运算地~)
所以本地32位系统运行的其实是: ((int) $i) % 4 即 512559680 % 4
解决方法 : 最后为了保持与其他平台的一致,强制在64系统也”溢出” : ($i & 0xFFFFFFFF) % 4
————————————————
php也是一个比较无厘头的东西~