月度归档:2012年12月

Automatic JavaScript and CSS Packer

Notes

  • JavaScript packing only works with PHP5. If you're using PHP4 the scripts will still be merged into one file, but not packed.
  • A sample .htaccess file is included in the zip. Rename it and drop it in js/packed and css/packed for improved performance.

Download

A zip of the code and .htaccess can be found here: http://github.com/mcurry/cakephp/tree/master/helpers/asset, as well as posted below.

Instructions

  1. You'll need a working version of CakePHP 1.2 installed.
  2. Download jsmin 1.1.0 (http://code.google.com/p/jsmin-php/) or later and put it in vendors/jsmin.
  3. Download CSSTidy 1.3 (http://csstidy.sourceforge.net/) or later and put the contents in vendors/csstidy.
  4. Download/copy+paste the helper and unzip it to app/views/helpers.
  5. Include the helper in any controller that will need it. Most likely you will put it in AppController so that it's available to all your controllers:

Tips

  • Remember to set the inline option to false for JS and CSS in your layout if you want them to be packed with the view scripts.
  • Setting DEBUG on will cause this helper to output the scripts the same way $scripts_for_layout would, effectifly turning it off while testing.
  • If you get a JavaScript error with a packed version of a file it's most likely missing a semi-colon somewhere.
  • Order is important. If you include script1 then script2 on one view and script2 then script1 on another, they will generate separate packed versions and will be treated by the browser as separate scripts.

Helper Class:

<?php
/*
* Asset Packer CakePHP Component
* Copyright (c) 2008 Matt Curry
* www.PseudoCoder.com
* http://www.pseudocoder.com/archives/2007/08/08/automatic-asset-packer-cakephp-helper
*
* @author mattc <matt@pseudocoder.com>
* @version 1.2
* @license MIT
*
*/

class AssetHelper extends Helper {
//Cake debug = 0 packed js/css returned. $this->debug doesn't do anything.
//Cake debug > 0, $this->debug = false essentially turns the helper off. js/css not packed. Good for debugging your js/css files.
//Cake debug > 0, $this->debug = true packed js/css returned. Good for debugging this helper.
var $debug = false
;

//there is a *minimal* perfomance hit associated with looking up the filemtimes
//if you clean out your cached dir (as set below) on builds then you don't need this.
var $checkTS = true
;

//the packed files are named by stringing together all the individual file names
//this can generate really long names, so by setting this option to true
//the long name is md5'd, producing a resonable length file name.
var $md5FileName = false
;

//you can change this if you want to store the files in a different location.
//this is relative to your webroot/js and webroot/css paths
var $cachePath = 'packed/'
;

//set the css compression level
//options: default, low_compression, high_compression, highest_compression
//default is no compression
//I like high_compression because it still leaves the file readable.
var $cssCompression = 'high_compression'
;

var $helpers = array('Html', 'Javascript');
var
$viewScriptCount = 0
;

//flag so we know the view is done rendering and it's the layouts turn
function afterRender
() {
$view =& ClassRegistry::getObject('view'
);
$this->viewScriptCount = count($view->__scripts
);
}

function scripts_for_layout() {
$view =& ClassRegistry::getObject('view'
);

//nothing to do
if (!$view->__scripts
) {
return;
}

//move the layout scripts to the front
$view->__scripts = array_merge
(
array_slice($view->__scripts, $this->viewScriptCount
),
array_slice($view->__scripts, 0, $this->viewScriptCount
)
);

if (Configure::read('debug') && $this->debug == false) {
return
join("\n\t", $view->__scripts
);
}

//split the scripts into js and css
foreach ($view->__scripts as $i => $script
) {
if (
preg_match('/js\/(.*).js/', $script, $match
)) {
$temp
= array();
$temp['script'] = $match[1
];
$temp['name'] = basename($match[1
]);
$js[] = $temp
;

//remove the script since it will become part of the merged script
unset($view->__scripts[$i
]);
} else if (
preg_match('/css\/(.*).css/', $script, $match
)) {
$temp
= array();
$temp['script'] = $match[1
];
$temp['name'] = basename($match[1
]);
$css[] = $temp
;

//remove the script since it will become part of the merged script
unset($view->__scripts[$i
]);
}
}

$scripts_for_layout = '';
//first the css
if (!empty($css
)) {
$scripts_for_layout .= $this->Html->css($this->cachePath . $this->process('css', $css
));
$scripts_for_layout .= "\n\t"
;
}

//then the js
if (!empty($js
)) {
$scripts_for_layout .= $this->Javascript->link($this->cachePath . $this->process('js', $js
));
}

//finally anything that was left over, usually codeBlocks
$scripts_for_layout .= join("\n\t", $view->__scripts
);

return $scripts_for_layout;
}

function process($type, $data) {
switch (
$type
) {
case
'js'
:
$path = JS
;
break;
case
'css'
:
$path = CSS
;
break;
}

$folder = new Folder;

//make sure the cache folder exists
if ($folder->create($path . $this->cachePath, "777"
)) {
trigger_error('Could not create ' . $path . $this->
cachePath
. '. Please create it manually with 777 permissions', E_USER_WARNING
);
}

//check if the cached file exists
$names = Set::extract($data, '{n}.name'
);
$folder->cd($path . $this->cachePath
);
$fileName = $folder->find($this->__generateFileName($names) . '_([0-9]{10}).' . $type
);
if (
$fileName
) {
//take the first file...really should only be one.
$fileName = $fileName[0
];
}

//make sure all the pieces that went into the packed script
//are OLDER then the packed version
if ($this->checkTS && $fileName
) {
$packed_ts = filemtime($path . $this->cachePath . $fileName
);

$latest_ts = 0;
$scripts = Set::extract($data, '{n}.script'
);
foreach(
$scripts as $script
) {
$latest_ts = max($latest_ts, filemtime($path . $script . '.' . $type
));
}

//an original file is newer. need to rebuild
if ($latest_ts > $packed_ts
) {
unlink($path . $this->cachePath . $fileName
);
$fileName = null
;
}
}

//file doesn't exist. create it.
if (!$fileName
) {
$ts = time
();

//merge the script
$scriptBuffer = ''
;
$scripts = Set::extract($data, '{n}.script'
);
foreach(
$scripts as $script
) {
$buffer = file_get_contents($path . $script . '.' . $type
);

switch ($type) {
case
'js'
:
//jsmin only works with PHP5
if (PHP5
) {
vendor('jsmin/jsmin'
);
$buffer = trim(JSMin::minify($buffer
));
}
break;

case 'css':
vendor('csstidy/class.csstidy'
);
$tidy = new csstidy
();
$tidy->load_template($this->cssCompression
);
$tidy->parse($buffer
);
$buffer = $tidy->print->plain
();
break;
}

$scriptBuffer .= "\n/* $script.$type */\n" . $buffer;
}

//write the file
$fileName = $this->__generateFileName($names) . '_' . $ts . '.' . $type
;
$file = new File($path . $this->cachePath . $fileName
);
$file->write(trim($scriptBuffer
));
}

if ($type == 'css') {
//$html->css doesn't check if the file already has
//the .css extension and adds it automatically, so we need to remove it.
$fileName = str_replace('.css', '', $fileName
);
}

return $fileName;
}

function __generateFileName($names) {
$fileName = str_replace('.', '-', implode('_', $names
));

if ($this->md5FileName) {
$fileName = md5($fileName
);
}

return $fileName;
}
}
?>

link form : http://bakery.cakephp.org/articles/mattc/2008/10/26/automatic-javascript-and-css-packer

eclipse software update

示例:

http://mirror.bit.edu.cn/eclipse/releases/

eclipse国内镜像站可以在下载eclipse的时候得到.

国内镜像根据eclipse源,把 http://download.eclipse.org/ 替换为 http://mirrors.ustc.edu.cn/eclipse/ ,其他的也可以据此修改,然后把默认的禁用,启用自己添加的。

示例:

北京理工大学 http://mirror.bit.edu.cn/eclipse/
中国科学技术大学 http://mirrors.ustc.edu.cn/eclipse/
大连东软信息学院 http://mirrors.neusoft.edu.cn/eclipse/

SVN:

一般不直接从网上安装,太慢太慢
应从官方网站上下载安装包,然后再用eclipse的software update工具安装,这样速度一般很快。
我的1m的adsl,如果直接网上安装,大概1k下载速度,直接http下载安装包,大概在50-100k之间,差别够大吧?

步骤如下:

1. 下载subversive
进入这个网址 http://www.eclipse.org/subversive/downloads.php, 找到Latest Release - Recommended 在 Subversive plug-in - [required]下找到
如:
Subversive-3.0.5.I20160701-1700.zip
Subversive-4.0.4.I20170216-1700.zip

2. 下载svn connector

在刚才上面的链接下方,有svn connector的说明,给出下载地址
a. http://www.polarion.com/products/svn/subversive.php?src=eclipseproject
b. https://polarion.plm.automation.siemens.com/products/svn/subversive/download
在这里找到Subversive Connector Archives,有链接指向安装包,将它下载下来,具体地址是:

http://community.polarion.com/projects/subversive/download/eclipse/4.0/builds/
http://community.polarion.com/projects/subversive/download/eclipse/6.0/builds/
http://community.polarion.com/projects/subversive/download/eclipse/5.0/builds/

    6.0 Subversive Connector Archives for Subversive 4.0
    5.0 Subversive Connector Archives for Subversive 3.0
    4.0 Subversive Connector Archives for Subversive 2.0

3. 安装subversive

eclispe -> software updates -> available software -> Manage Sites
首先取消所有site,否则eclipse还是要去更新一些东西
然后add -> archive,指向刚才下载的Subversive-3.0.5.I20160701-1700.zip文件,小心add之后software updates工具会自动勾选几个eclipse的站点,千万记住再次取消他们,只保留subversive一个。之后就一路顺利安装,完成后会要求重启。

4. 安装svn connector

和上面的方式一致。
注意在选择安装内容时,全选,我开始只选了一个svn connector,结果不能用, subversive的设置中无法选择connector。后来第二次安装时全选就能用了。

5. 设置svn connector
eclipse -> windows -> preferences -> team -> svn
点SVN Connector,然后选择一个要用的connector,我选择的是SVN Kit(SVN/1.5.5 r5428),apply.

SVN KIT:

https://svnkit.com/download.php

PHP & APC

1.下载APC扩展文件
apc-igbinary-fastlz-snap20110301-5.3-ts-vc9-x86.zip
(下载地址:http://downloads.php.net/pierre/)
将解压后的文件php_apc.dll放到  php/ext下

2.编辑PHP.INI
(1)添加 extension=php_apc.dll
(2)将下列内容添加到php.ini文件中
apc.enabled = 1
apc.shm_segments = 1
apc.shm_size = 64
apc.max_file_size = 10M
apc.stat=1

3.测试
(1)重启apache服务器,运行phpinfo,查看apc模块是否安装成功
(2)下载apc控制面板,下载地址:http://pecl.php.net/package/apc
随便下载一个版本的APC,然后取里面的apc.php,运行apc.php,出现如下结果
点击查看原图

4.apc参数说明
http://cn.php.net/manual/en/apc.configuration.php#ini.apc.optimization

php错误和异常

任何程序员在开发时都可能遇到过一些失误,或其他原因造成错误的发生。当然,用户如果不愿意或不遵循应用程序的约束,也会在使用时引起一些错误发生。PHP程序的错误发生一般归属于下列三个领域。

Ø  语法错误

语法错误最常见,并且最容易修复。例如,遗漏了一个分号,就会显示错误信息。这类错误会阻止脚本执行。通常发生在程序开发时,可以通过错误报告进行修复,再重新运行。

Ø  运行时错误

这种错误一般不会阻止PHP脚本的运行,但是会阻止脚本做希望它所做的任何事情。例如,在调用header()函数前如果有字符输出,PHP通常会显示一条错误消息,虽然PHP脚本继续运行,但header()函数并没有执行成功。

Ø  逻辑错误

这种错误实际上是最麻烦的,不但不会阻止PHP脚本的执行,也不会显示出错误消息。例如,在if语句中判断两个变量的值是否相等,如果错把比较运行符号“==”写成赋值运行符号“=”就是一种逻辑错误,很难会被发现。


个异常则是在一个程序执行过程中出现的一个例外,或是一个事件,它中断了正常指令的运行,跳转到其他程序模块继续执行。所以异常处理经常被当做程序的控制
流程使用。无论是错误还是异常,应用程序都必须能够以妥善的方式处理,并做出相应的反应,希望不要丢失数据或者导致程序崩溃。

10.1.1  错误类型和基本的调试方法

运行PHP脚本时,PHP解析器会尽其所能地报告它遇到的问题。在PHP中错误报告的处理行为,都是通过PHP的配置文件php.ini中有关的配置指令确定的。另外PHP的错误报告有很多种级别,可以根据不同的错误报告级别提供对应的调试方法。一旦把PHP设置成呈现出发生了哪些错误,你可能想调整错误报告的级别。在表10-1中列出了PHP中大多数的错误报告级别。

10-1  PHP的错误报告级别

<DIV align=center>

级别常量

错误报告描述

E_ERROR 

致命的运行时错误(它会阻止脚本的执行)

E_WARNING 

运行时警告(非致命的错误)

E_PARSE 

从语法中解析错误

E_NOTICE 

运行时注意消息(可能是或者可能不是一个问题)

E_CORE_ERROR 

类似E_ERROR,但不包括PHP核心造成的错误

E_CORE_WARNING 

类似E_WARNING,但不包括PHP核心错误警告

E_COMPILE_ERROR 

致命的编译时错误

E_COMPILE_WARNING 

致命的编译时警告

E_USER_ERROR 

用户导致的错误消息

E_USER_WARNING 

用户导致的警告

E_USER_NOTICE 

用户导致的注意消息

E_ALL 

所有的错误、警告和注意

E_STRICT

关于PHP版本移植的兼容性和互操作性建议

</DIV>

如果用户希望在PHP脚本中,遇到上表中的某个级别的错误时,将错误消息报告给用户。则必须在配置文件php.ini中,将display_errors指令的值设置为On,开启PHP输出错误报告的功能。也可以在PHP脚本中调用ini_set()函数,动态设置配置文件php.ini中的某个指令。如果display_errors
启用,就会显示满足已设置的错误级别的所有错误。当用户在访问时,看到显示的这些消息不仅会感到迷惑,而且还可能会过多地泄露有关服务器的信息,使服务器
变得很不安全。所以在项目开发或测试期间启用此指令,可以根据不同的错误报告更好的调试程序。出于安全性和美感的目的,让公众用户查看
PHP的详细出错消息一般是不明智的,所以在网站投入使用时要将其禁用。

当你正在开发站点时,你将希望PHP报告特定类型的错误,可以通过调整错误报告的级别实现,可以通过以下两种方法设置错误报告级别。

Ø  可以通过在配置文件php.ini中,修改配置指令error_reporting的值,修改成功后重新启动Web服务器,则每个PHP脚本都可以按调整后的错误级别输出错误报告。下面是修改php.ini配置文件的示例,列出几种为error_reporting指令设置不同级别值的方式,可以把位运算符[&(与)、|(或)、~(非)]和错误级别常量一起使用。如下所示:

<DIV align=center>

; 可以抛出任何非注意的错误,默认值

error_reporting = E_ALL & ~E_NOTICE

; 只考虑致命的运行时错误、解析错误和核心错误

; error_reporting = E_ERROR | E_PARSE | E_CORE_ERROR

; 报告除用户导致的错误之外的所有错误

; error_reporting = E_ALL & ~(E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE)

</DIV>

Ø  或者可以在PHP脚本中使用error_reporting()函数,基于各个脚本来调整这种行为。这个函数用于确定PHP应该在特定的页面内报告哪些类型的错误。该函数获取一个数字或上表中错误级别常量作为参数。如下所示:

<DIV align=center>

error_reporting(0);                                 //设置为0会完全关闭错误报告

error_reporting (E_ALL);                          //将会向PHP报告发生的每个错误

error_reporting (E_ALL & ~E_NOTICE);           //可以抛出任何非注意的错误报告

</DIV>

在下面的示例中,我们在PHP脚本中分别创建出一个“注意”、一个“警告”和一个致命“错误”。并通过设置不同的错误级别,限制程序输出没有被允许的错误报告。创建一个名为error.php的脚本文件,代码如下所示:

<DIV align=center>

<html>

         <head><title>测试错误报告</title></head>

         <body>

                   <h2>测试错误报告</h2>

                   <?php

                            /*开启php.ini中的display_errors指令,只有该指令开启如果有错误报告才能输出*/

                            ini_set('display_errors',1); 

                            /*通过error_reporting()函数设置在本脚本中,输出所有级别的错误报告*/

                            error_reporting(E_ALL);

                            /*“注意(notice)”的报告,不会阻止脚本的执行,并且可能不一定是一个问题 */

                            getType($var);             //调用函数时提供的参数变量没有在之前声明

                            /*“警告(warning)”的报告,指示一个问题,但是不会阻止脚本的执行 */

                            getType();                 //调用函数时没有提供必要的参数

                            /*“错误(error)”的报告,它会终止程序,脚本不会再向下执行 */

                            get_Type();                //调用一个没有被定义的函数

                   ?>

         </body>

</html>

</DIV>

在上面的脚本中,为了确保配置文件中的display_errors指令开启,通过ini_set()函数强制在该脚本执行中启动,并通过error_repoting()函数设置错误级别为E_ALL,报告所有错误、警告和注意。并在脚本中分别创建出注意、警告和错误,PHP脚本只有在遇到错误时才会终止运行,输出的错误报告结果如图10-1所示。

点击查看原图

10-1  输出错误报告结果的演示

“注意”和“警告”的错误报告并不会终止程序运行。如果在上面的输出结果中,不希望有注意和警告的报告输出,就可以在脚本error.php中修改error_repoting()函数,修改的代码如下所示:

<DIV align=center>

error_reporting(E_ALL&~(E_WARNING | E_NOTICE));        //报告除注意和警告之外的所有错误

</DIV>

脚本error.php被修改以后并重新运行,在输出的结果中就只剩下一条错误报告了,如图10-2所示。

点击查看原图

10-2  屏蔽“注意”和“警告”后的输出结果

除了使用error_reportingdisplay_error两个配置指令可以修改错误报告行为以外,还有许多配置指令可以确定PHP的错误报告行为。其他的一些重要的指令如表10-2所示。

10-2  确定PHP错误报告行为的配置指令

<DIV align=center>

配置指令

   

默 认 值

display_startup_errors

是否显示PHP引擎在初始化时遇到的所有错误

Off

log_errors

确定日志语句记录的位置

Off

error_log

设置错误可以发送到syslog

Null

log_errors_max_len

每个日志项的最大长度,以字节为单位,设置0表示指定最大长度

1024

ignore_repeated_errors

是否忽略同一文件、同一行发生的重复错误消息

Off

ignore_repeated_source

忽略不同文件中或同一文件中不同行上发生的重复错误

Off

track_errors

启动该指令会使PHP$php_errormsg中存储最近发生的错误信息

Off

</DIV>

10.1.2  错误日志

对于PHP开发者来说,一旦某个产品投入使用,应该立即将display_errors
项关闭,以免因为这些错误所透露的路径、数据库连接、数据表等信息而遭到黑客攻击。但是,任何一个产品在投入使用后,都难免会有错误出现,那么如何记录一
些对开发者有用的错误报告呢?我们可以在单独的文本文件中将错误报告作为日志记录。错误日志的记录,可以帮助开发人员或者管理人员查看系统是否存在问题。

如果需要将程序中的错误报告写入错误日志中,只要在PHP的配置文件中,将配置指令log_errors开启即可。错误报告默认就会记录到Web服务器的日志文件里,例如记录到Apache服务器的错误日志文件error.log中。当然也可以记录错误日志到指定的文件中或发送给系统syslog,分别介绍如下:

1.使用指定的文件记录错误报告日志

如果使用自己指定的文件记录错误日志,一定要确保将这个文件存放在文档根目录之外,以减少遭到攻击的可能。并且该文件一定要让PHP脚本的执行用户(Web服务器进程所有者)具有写权限。假设在Linux操作系统中,将/usr/local/目录下的error.log文件作为错误日志文件,并设置Web服务器进程用户具有写的权限。然后在PHP的配置文件中,将error_log指令的值设置为这个错误日志文件的绝对路径。需要将php.ini中的配置指令做如下修改:

<DIV align=center>

error_reporting  =  E_ALL                        ;将会向PHP报告发生的每个错误

display_errors = Off                            ;不显示满足上条指令所定义规则的所有错误报告

log_errors = On                                ;决定日志语句记录的位置

log_errors_max_len = 1024                        ;设置每个日志项的最大长度

error_log = /usr/local/error.log                      ;指定产生的错误报告写入的日志文件位置

</DIV>

PHP的配置文件按上面的方式设置完成以后,并重新启动Web服务器。这样,在执行PHP的任何脚本文件时,所产生的所有错误报告都不会在浏览器中显示,而会记录在自己指定的错误日志/usr/local/error.log中。此外,不仅可以记录满足error_reporting所定义规则的所有错误,而且还可以使用PHP中的error_log()函数,送出一个用户自定义的错误信息。该函数的原型如下所示:

<DIV align=center>

bool error_log ( string message [, int message_type [, string destination [, string extra_headers]]] )

</DIV>

此函数会送出错误信息到Web服务器的错误日志文件、某个TCP服务器或到指定文件中。该函数执行成功则返回TRUE,失败则返回FALSE。第一个参数message 是必选项,即为要送出的错误信息。如果仅使用这一个参数,会按配置文件php.ini中所设置的位置处发送消息。第二个参数message_type为整数值:0表示送到操作系统的日志中;1则使用PHPMail()函数,发送信息到某E-mail处,第四个参数extra_headers亦会用到;2则将错误信息送到TCP 服务器中,此时第三个参数destination表示目的地IPPort3则将信息存到文件destination中。如果以登入Oracle数据库出现问题的处理为例,该函数的使用如下所示:

<DIV align=center>

<?php  

         if(!Ora_Logon($username, $password)){  

                   error_log("Oracle数据库不可用!", 0);               //将错误消息写入到操作系统日志中

         }

         if(!($foo=allocate_new_foo()){

                   error_log("出现大麻烦了!", 1, "webmaster@www.mydomain.com");   //发送到管理员邮箱中

         }

         error_log("搞砸了!",   2,   "localhost:5000");            //发送到本机对应5000端口的服务器中

         error_log("搞砸了!",   3,   "/usr/local/errors.log");        //发送到指定的文件中

?> 

</DIV>

2.错误信息记录到操作系统的日志里

错误报告也可以被记录到操作系统日志里,但不同的操作系统之间的日志管理有点区别。在Linux上错误语句将送往syslog,而在Windows上错误将发送到事件日志里。如果你不熟悉syslog,起码要知道它是基于UNIX的日志工具,它提供了一个API来记录与系统和应用程序执行有关的消息。Windows事件日志实际上与UNIXsyslog相同,这些日志通常可以通过事件查看器来查看。如果希望将错误报告写到操作系统的日志里,可以在配置文件中将error_log指令的值设置为syslog。具体需要在php.ini中修改的配置指令如下所示:

<DIV align=center>

error_reporting  =  E_ALL                      ;将会向PHP报告发生的每个错误

display_errors = Off                                   ;不显示满足上条指令所定义规则的所有错误报告

log_errors = On                               ;决定日志语句记录的位置

log_errors_max_len = 1024                      ;设置每个日志项的最大长度

error_log = syslog                             ;指定产生的错误报告写入操作系统的日志里

</DIV>

除了一般的错误输出之外,PHP还允许向系统syslog中发送定制的消息。虽然通过前面介绍的error_log()函数,也可以向syslog中发送定制的消息,但在PHP中为这个特性提供了需要一起使用的4个专用函数。分别介绍如下:

 

Ø  define_syslog_variables()

在使用openlog()syslogcloselog()三个函数之前必须先调用该函数。因为在调用该函数时,它会根据现在的系统环境为下面三个函数初使用化一些必需的常量。

Ø  openlog()

打开一个和当前系统中日志器的连接,为向系统插入日志消息做好准备。并将提供的第一个字符串参数插入到每个日志消息中,该函数还需要指定两个将在日志上下文使用的参数,可以参考官方文档使用。

Ø  syslog()

该函数向系统日志中发送一个定制消息。需要两个必选参数,第一个参数通过指定一个常量定制消息的优先级。例如LOG_WARNING表示一般的警告,LOG_EMERG表示严重地可以预示着系统崩溃的问题,一些其他的表示严重程度的常量可以参考官方文档使用。第二个参数则是向系统日志中发送的定制消息,需要提供一个消息字符串,也可以是PHP引擎在运行时提供的错误字符串。

Ø  closelog()

该函数在向系统日志中发送完成定制消息以后调用,关闭由openlog()函数打开的日志连接。

如果在配置文件中,已经开启向syslog发送定制消息的指令,就可以使用前面介绍的四个函数发送一个警告消息到系统日志中,并通过系统中的syslog解析工具,查看和分析由PHP程序发送的定制消息,如下所示:

<DIV align=center>

<?php

         define_syslog_variables();

         openlog("PHP5", LOG_PID , LOG_USER);

         syslog(LOG_WARNING, "警告报告向syslog中发送的演示,警告时间:".date("Y/m/d H:i:s"));

         closelog();

?>

</DIV>

Windows系统为例,通过右击“我的电脑”选择管理选项,然后到系统工具菜单中,选择事件查看器,再找到应用程序选项,就可以看到我们自己定制的警告消息了。上面这段代码将在系统的syslog文件中,生成类似下面的一条信息,是事件的一部分:

<DIV align=center>

PHP5[3084], 警告报告向syslog发送的演示,警告间:2009/03/26 04:09:11.

</DIV>

使用指定的文件还是使用syslog记录错误日志,取决于你所在的Web服务器环境。如果你可以控制Web服务器,使用syslog是最理想的,因为你能利用syslog的解析工具来查看和分析日志。但如果你的网站在共享服务器的虚拟主机中运行,就只有使用单独的文本文件记录错误日志了。

10.1.3  异常处理

异常(Exception)处理用于在指定的错误发生时改变脚本的正常流程,是PHP 5中的一个新的重要特性。异常处理是一种可扩展、易维护的错误处理统一机制,并提供了一种新的面向对象的错误处理方式。在JavaC#Python

语言中很早就提供了这种异常处理机制,如果你对哪一种语言中的异常处理熟悉,那对PHP中提供的异常处理机制也不会陌生。

1.异常处理实现

异常处理和编写程序的流程控制相似,所以也可以通过异常处理实现一种另类的条件选择结构。异常就是在程序运行过程中出现的一些意料之外的事件,如果不对此事件进行处理,则程序在执行时遇到异常将崩溃。处理异常需要在PHP脚本中使用以下语句:

<DIV align=center>

try {                     //所有需要进行异常处理的代码都必须放入这个代码块内

   … …                  //在这里可以使用throw语句抛出一个异常对象

}catch(ex1) {               //使用该代码块捕获一个异常,并进行处理

   … …                 //处理发生的异常,也可再次抛出异常

}

</DIV>

PHP代码中所产生的异常可以被throw语句抛出并被catch语句捕获。需要进行异常处理的代码都必须放入try代码块内,以便捕获可能存在的异常。每一个try至少要有一个与之对应的catch,也不能出现单独的catch,另外trycache之间也不能有任何的代码出现。一个异常处理的简单实例如下所示:

<DIV align=center>

<?php

         try {

                   $error = 'Always throw this error';

                   throw new Exception($error);      //创建一个异常对象,通过throw语句抛出

                   echo 'Never executed';            //从这里开始,try代码块内的代码将不会再被执行

         } catch (Exception $e) {

                   echo 'Caught exception: ',  $e->getMessage(), "\n";  //输出捕获的异常消息

         }

         echo 'Hello World';                    //程序没有崩溃继续向下执行

?>

</DIV>

在上面的代码中,如果try代码块中出现某些错误,我们就可以执行一个抛出异常的操作。在某些编程语言中,例如Java,在出现异常时将自动抛出异常。而在PHP中,异常必须手动抛出。throw关键字将触发异常处理机制,它是一个语言结构,而不是一个函数,但必须给它传递一个对象作为值。在最简单的情况下,可以实例化一个内置的Exception类,就像以上代码所示那样。如果在try语句中有异常对象被抛出,该代码块不会再继续向下执行,而直接跳转到catch中执行。并传递给catch代码块一个对象,也可以理解为被catch代码块捕获的对象,其实就是导致异常被throw语句抛出的对象。在catch代码块中可以简单的输出一些异常的原因,也可以是try代码块中任务的另一个版本解决方案,此外,也可以在这个catch代码块中产生新的异常。最重要的是,在异常处理之后,程序不会崩溃,而会继续执行。

2.扩展PHP内置的异常处理类

try代码块中,需要使用throw语句抛出一个异常对象,才能跳转到catch代码块中执行,并在catch代码块中捕获并使用这个异常类的对象。虽然在PHP中提供的内置异常处理类Exception,已经具有非常不错的特性,但在某些情况下,可能还要扩展这个类来得到更多的功能。所以用户可以用自定义的异常处理类来扩展PHP内置的异常处理类。以下的代码说明了在内置的异常处理类中,哪些属性和方法在子类中是可访问和可继承的:

内置的异常处理类(Exception

<DIV align=center>

<?php

         class Exception {

           protected $message = 'Unknown exception';              //异常信息

           protected $code = 0;                              //用户自定义异常代码

           protected $file;                                   //发生异常的文件名

           protected $line;                                  //发生异常的代码行号

 

           function __construct($message = null, $code = 0){}    //构造方法

 

           final function getMessage(){}                        //返回异常信息

           final function getCode(){}                           //返回异常代码

           final function getFile(){}                            //返回发生异常的文件名

       final function getLine(){}                            //返回发生异常的代码行号

         final function getTrace(){}                           //backtrace() 数组

          final function getTraceAsString(){}                    //已格成化成字符串的 getTrace() 信息

 

           /* 可重载的方法 */

           function __toString(){}                             //可输出的字符串

         }

?>

</DIV>

上面这段代码只为说明内置异常处理类Exception的结构,它并不是一段有实际意义的可用代码。如果使用自定义的类作为异常处理类,则必须是扩展内置异常处理类Exception的子类,非Exception类的子类是不能作为异常处理类使用的。如果在扩展内置处理类Exception时重新定义构造函数的话,建议同时调用parent::construct()来检查所有的变量是否已被赋值。当对象要输出字符串的时候,可以重载__toString()并自定义输出的样式。可以在自定义的子类中,直接使用内置异常处理Exception类中的所有成员属性,但不能重新改写从该父类中继承过来的成员方法,因为该类的大多数公有方法都是final的。

创建自定义的异常处理程序非常简单,和传统类的声明方式相同,但该类必须是内置异常处理类Exception的一个扩展。当PHP中发生异常时,可调用自定义异常类中的方法进行处理。创建一个自定义的MyException类,继承了内置异常处理类Exception中的所有属性,并向其添加了自定义的方法。代码及应用如下所示:

扩展PHP内置的异常处理类的应用

<DIV align=center>

<?php

         /* 自定义的一个异常处理类,但必须是扩展内异常处理类的子类 */

         class MyException extends Exception{

                   //重定义构造器使第一个参数 message 变为必须被指定的属性

                   public function __construct($message, $code=0){

                            //可以在这里定义一些自己的代码

                            //建议同时调用 parent::construct()来检查所有的变量是否已被赋值

                            parent::__construct($message, $code);

                   }

                  

                   public function __toString() {             //重写父类方法,自定义字符串输出的样式

                            return __CLASS__.":[".$this->code."]:".$this->message."<br>";

                   }

                  

                   public function customFunction() {       //为这个异常自定义一个处理方法

                            echo "按自定义的方法处理出现的这个类型的异常<br>";

                   }

         }

        

         try {                                    //使用自定义的异常类捕获一个异常,并处理异常

                   $error = '允许抛出这个错误';      

                   throw new MyException($error);         //创建一个自定义的异常类对象,通过throw语句抛出

                   echo 'Never executed';                 //从这里开始,try代码块内的代码将不会再被执行

         } catch (MyException $e) {                 //捕获自定义的异常对象

                   echo '捕获异常: '.$e;                  //输出捕获的异常消息

                   $e->customFunction();                //通过自定义的异常对象中的方法处理异常

         }

         echo '你好呀';                             //程序没有崩溃继续向下执行

?>

</DIV>

在自定义的MyException类中,使用父类中的构造方法检查所有的变量是否已被赋值。而且重载了父类中的__toString()方法,输出自己定制捕获的异常消息。自定义和内置的异常处理类,在使用上没有多大区别,只不过在自定义的异常处理类中,可以调用为具体的异常专门编写的处理方法。

3.捕获多个异常

try代码块之后,必须至少给出一个catch代码块,也可以将多个catch代码块与一个try代码块进行关联。如果每个catch代码块可以捕获一个不同类型的异常,那么使用多个catch就可以捕获不同的类所产生的异常。当产生一个异常时,PHP将查询一个匹配的catch代码块。如果有多个catch代码块,传递给每一个catch代码块的对象必须具有不同的类型,这样PHP可以找到需要进入哪一个catch代码块。当try代码块不再抛出异常或者找不到catch能匹配所抛出的异常时,PHP代码就会在跳转到最后一个 catch 的后面继续执行。多个异常的捕获的示例如下:

内置的异常处理类(Exception

<DIV align=center>

<?php

         /* 自定义的一个异常处理类,但必须是扩展内异常处理类的子类 */

         class MyException extends Exception{

                   //重定义构造器使第一个参数 message 变为必须被指定的属性

                   public function __construct($message, $code=0){

                            //可以在这里定义一些自己的代码

                            //建议同时调用 parent::construct()来检查所有的变量是否已被赋值

                            parent::__construct($message, $code);

                   }

                   //重写父类中继承过来的方法,自定义字符串输出的样式

                   public function __toString() {

                            return __CLASS__.":[".$this->code."]:".$this->message."<br>";

                   }

 

                   //为这个异常自定义一个处理方法

                   public function customFunction() {

                            echo "按自定义的方法处理出现的这个类型的异常";

                   }

         }

        

         /* 创建一个用于测试自定义扩展的异常类MyException */

         class TestException {

                   public $var;                          //一个成员属性,用来判断对象是否创建成功被初始化

 

                   function __construct($value=0) {        //通过构造方法的传值决定抛出的异常

                            switch($value){                 //对传入的值进行选择性的判断

                                     case 1:                    //如果传入的参数值为1,则抛出自定义的异常对象

                                               throw new MyException("传入的值“1 是一个无效的参数", 5);

                                               break;

                                     case 2:                      //如果传入的参数值为2,则抛出PHP内置的异常对象

                                               throw new Exception("传入的值“2”不允许作为一个参数", 6);

                                               break;

                                     default:                    //如果传入的参数值合法,则不抛出异常创建对象成功

                                               $this->var=$value;      //为对象中的成员属性赋值

                                               break;

                            }

                   }

         }

     //示例1,在没有异常时,程序正常执行,try中的代码全部执行并不会执行任何catch区块

         try{

                   $testObj=new TestException();              //使用默认参数创建异常的测试类对象

                   echo "***********<br>";                 //没有抛出异常这条语句就会正常执行

         }catch(MyException $e){                      //捕获用户自定义的异常区块

                   echo "捕获自定义的异常:$e <br>";        //按自定义的方式输出异常消息

                   $e->customFunction();                     //可以调用自定义的异常处理方法

         }catch(Exception $e) {                         //捕获PHP内置的异常处理类的对象

                   echo "捕获默认的异常:".$e->getMessage()."<br>";   //输出异常消息

         }     

         var_dump($testObj);          //判断对象是否创建成功,如果没有任何异常,则创建成功

 

    //示例2,抛出自定义的异常,并通过自定义的异常处理类捕获这个异常并处理

         try{

                   $testObj1=new TestException(1);           //传入参数1时,创建测试类对象抛出自定义异常

                   echo "***********<br>";                 //这个语句不会被执行

         }catch(MyException $e){                      //这个catch区块中的代码将被执行

                   echo "捕获自定义的异常:$e <br>";

                   $e->customFunction();

         }catch(Exception $e) {                         //这个catch区块不会执行

                   echo "捕获默认的异常:".$e->getMessage()."<br>";

         }     

         var_dump($testObj1);                          //有异常产生,这个对象没有创建成功

 

    //示例2,抛出内置的异常,并通过自定义的异常处理类捕获这个异常并处理

         try{

                   $testObj2=new TestException(2);            //传入参数2时,创建测试类对象抛出内置异常

                   echo "***********<br>";                   //这个语句不会被执行

         }catch(MyException $e){                        //这个catch区块不会执行

                   echo "捕获自定义的异常:$e <br>";

                   $e->customFunction();

         }catch(Exception $e) {                           //这个catch区块中的代码将被执行

                   echo "捕获默认的异常:".$e->getMessage()."<br>";

         }     

         var_dump($testObj2);                            //有异常产生,这个对象没有创建成功

?>

</DIV>

在上面代码中,可以使用两个异常处理类:一个是自定义的异常处理类MyException;另一个则是PHP中内置的异常处理类Exception。分别在try区块中创建测试类TestException的对象,并根据构造方法中提供的不同数字参数,抛出自定义异常类对象、内置的异常类对象和不抛出任何异常的情况,跳转到对应的catch区块中执行。如果没有异常发生,则不会进入任何一个catch块中执行,测试类TestException的对象创建成功。

base62

新浪微博的mid地址转换成短格式编码的方法,例如:

221110410216147026

转换后:

zF4mOFpN7A

比如新浪微博地址可以组装成这样:http://weibo.com/1642634100/5en0UftjV8H,其中数字是用户的id,后面的字符串是base62加密后的mid,因此通过组装这两个,可以得到信息的主体。

本文的代码,是由http://forum.open.weibo.com/read.php?tid=3236&uid=89934的博主的js代码改成php而来

贴下代码,运行和博主的一样,这里只是将mid转成短格式,其实逆向也很好改了:

<?php

$str62keys = array(

"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",

"a", "b", "c", "d", "e", "f", "g", "h", "i", 

"j", "k", "l", "m", "n", "o", "p", "q", 

"r", "s", "t", "u", "v", "w", "x", "y", 

"z","A", "B", "C", "D", "E", "F", "G", "H", 

"I", "J", "K", "L", "M", "N", "O", "P", 

"Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"

);



/**

 * 10进制值转换为62进制

 * @param {String} int10 10进制值

 * @return {String} 62进制值

 */

function int10to62($int10) {

global $str62keys;

$s62 = '';

$r = 0;

while ($int10 != 0)

{

$r = $int10 % 62;

$s62 = $str62keys[$r].$s62;

$int10 = floor($int10 / 62);

}

return $s62;

}

/**

 * 

 * 通过mid获得短格式

 * @param string $mid

 * @return 短格式

 */

function getCodeByMid($mid){

$url = '';

for ($i = strlen($mid) - 7; $i > -7; $i -=7) //从最后往前以7字节为一组读取mid

{

$offset1 = $i < 0 ? 0 : $i;

$offset2 = $i + 7;

$num = substr($mid, $offset1,$offset2-$offset1); 

//mid.substring(offset1, offset2);

$num = int10to62($num);

$url = $num .$url;

}

return $url;

}

echo getCodeByMid('221110410216147026');

?>


 为了方便,这里把那位博主的js代码也贴在这里,大家可以做一个对照:


/**
 * 新浪微博mid与url互转实用工具
 * 作者: XiNGRZ (http://weibo.com/xingrz)
 */


var WeiboUtility = {};


/**
 * 62进制字典
 */
WeiboUtility.str62keys = [
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", 
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t", 
"u", "v", "w", "x", "y", "z",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", 
"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", 
"U", "V", "W", "X", "Y", "Z"
];


/**
 * 62进制值转换为10进制
 * @param {String} str62 62进制值
 * @return {String} 10进制值
 */
WeiboUtility.str62to10 = function(str62) {
var i10 = 0;
for (var i = 0; i < str62.length; i++)
{
var n = str62.length - i - 1;
var s = str62[i];
i10 += this.str62keys.indexOf(s) * Math.pow(62, n);
}
return i10;
};


/**
 * 10进制值转换为62进制
 * @param {String} int10 10进制值
 * @return {String} 62进制值
 */
WeiboUtility.int10to62 = function(int10) {
var s62 = '';
var r = 0;
while (int10 != 0)
{
r = int10 % 62;
s62 = this.str62keys[r] + s62;
int10 = Math.floor(int10 / 62);
}
return s62;
};


/**
 * URL字符转换为mid
 * @param {String} url 微博URL字符,如 "wr4mOFqpbO"
 * @return {String} 微博mid,如 "201110410216293360"
 */
WeiboUtility.url2mid = function(url) {
var mid = '';
for (var i = url.length - 4; i > -4; i = i - 4) //从最后往前以4字节为一组读取URL字符
{
var offset1 = i < 0 ? 0 : i;
var offset2 = i + 4;
var str = url.substring(offset1, offset2);
str = this.str62to10(str);
if (offset1 > 0) //若不是第一组,则不足7位补0
{
while (str.length < 7)
{
str = '0' + str;
}
}
mid = str + mid;
}
return mid;
};


/**
 * mid转换为URL字符
 * @param {String} mid 微博mid,如 "201110410216293360"
 * @return {String} 微博URL字符,如 "wr4mOFqpbO"
 */
WeiboUtility.mid2url = function(mid) {
if (typeof(mid) != 'string') return false; //mid数值较大,必须为字符串!
var url = '';
for (var i = mid.length - 7; i > -7; i = i - 7) //从最后往前以7字节为一组读取mid
{
var offset1 = i < 0 ? 0 : i;
var offset2 = i + 7;
var num = mid.substring(offset1, offset2);
num = this.int10to62(num);
url = num + url;
}
return url;
};


 

htaccess

#
位于行首时表示注释。
[F]
Forbidden(禁止): 命令服务器返回 403 Forbidden错误给用户浏览器
[L]
Last rule(最后一条规则): 告诉服务器在本条规则执行完后停止重写URL
[N]
Next(下一条规则): 告诉服务器继续重写,指导所有重写指令都执行过
[G]
Gone(丢失): 命令服务器返回410 GONE(no longer exists)错误消息
[P]
Proxy(代理): 告诉服务器通过mod_proxy模块处理用户请求
[C]
Chain(捆绑): 告诉服务器将当前的规则和前面的规则进行捆绑
[R]
Redirect(重定向): 命令服务器发出重定向消息,以便用户浏览器发出rewritten/modified(重写/修改)URL的请求
[NC]
No Case(不区分大小写): 对客户端请求的URL不区分大小写
[PT]
Pass Through(放行): 让mod_rewrite模块将重写的URL传回给Apache做进一步处理
[OR]
Or(逻辑或): 用逻辑“或”将两个表达式连接在一起,如果结果为“真”,则会应用后继的相关规则
[NE]
No Escape(禁用转义): 命令服务器在输出时禁用转义字符
[NS]
No Subrequest(禁用子请求): 如果存在内部子请求,则跳过当前命令
[QSA]
Append Query String(追加查询字符串): 命令服务器在URL末尾追加查询字符串
[S=x]
Skip(跳过): 如果满足某指定的条件,则跳过后面第x调规则
[E=variable:value]
Environmental Variable(环境变量): 命令服务器将值value赋给变量variable
[T=MIME-type]
Mime Type(MIME类型): 声明目标资源所属的MIME类型
[]
匹配一个字符集合,例如[xyz]可以匹配x, y或者z
[]+
例如[xyz]+会以任何顺序、次数匹配x,y,z的出现
[^]
字符^表示字符集的补集。[^xyz]将匹配没有x,y或者z的字符串
[a-z]
连字符(-)表示匹配从字母a到字母z的所有字符串
a{n}
指定字母a出现的次数为n次,满足该条件时匹配。例如x{3}仅与xxx匹配
a{n,}
指定字母a出现的次数至少为n次,例如x{3,}可以与xxx或者xxxx等匹配
a{n,m}
指定a出现的次数至少为n到m次。
()
用于将正则表达式分组,满足第一组正则表达式的字符串会被存储在变量$1中,以此类推。如果括号中的不是正则表达式,例如(perishable)?press 将能够匹配有或者没有perishable前缀的press
^
位于行首。注意:和中括号中的[^]意义不同。
$
位于行末
?
例如 monzas? 会匹配 monza 或者 monzas,而 mon(za)? 会匹配 mon 或者 monza。又如 x? 会匹配“空字符” 或者 一个x
!
逻辑非。例如“!string” 将会匹配除了“string”以外的所有字符串
.
表示任意字符串
-
命令Apache“不要”重写URL,例如“xxx.domain.com.* – [F]”
+
匹配至少一个任意字符,例如G+匹配以G开头、并且后面至少有一个字符的字符串
*
匹配零个或多个字符,例如“.*”匹配任意字符串
|
逻辑“或”,与[OR]不同的是,它只匹配字符串,例如(x|y)匹配x或者y
\
转义字符。可以转义左括号( 尖字符^ 美元符号$ 感叹号! 点. 星号* 管道符号| 右括号) 等
\.
转义为点字符(点字符在正则表达式中可以匹配任意字符)
/*
零个或多个正斜杠
.*
零个或多个任意字符(即,匹配任意字符串,包括空字符)
^$
匹配“空字符”、“空行”
^.*$
匹配任意字符串(仅限一行)
[^/.]
匹配既非“正斜杠”也不是“点”的任意字符
[^/.]+
匹配第一个字符既非“正斜杠”也不是“点”,后继字符可以是“正斜杠”或者“点”的字符串
http://
匹配“http://”
^domain.*
匹配以“domain”开始的字符串
^domain\.com$
仅匹配“domain.com”
-d
测试字符串是否是已存在的目录
-f
测试字符串是否是已存在的文件
-s
测试字符串所指文件是否有“非零”值

HTTP协议重定向编码

  • 301 – Moved Permanently
  • 302 – Moved Temporarily
  • 403 – Forbidden
  • 404 – Not Found
  • 410 – Gone

gpg

A simple example

 

gpg --passphrase 111111 -c gpgtest.local

 

 

gpg --output gpgtest.local  --passphrase 111111 --decrypt gpgtest.local.gpg // The following is a brief command:

 

gpg -o gpgtest.local  --passphrase 111111 -d gpgtest.local.gpg

 

Note: The order seems very important. If you set the --passphrase and --output later than -c or --decrypt, it'll not work.

 

[root@se zhxue]# gpg --passphrase 111111 -c gpg.local
[root@se zhxue]# vi gpg.local
[root@se zhxue]# mv -f gpg.local.gpg gpg.local
[root@se zhxue]# vi gpg.local
[root@se zhxue]# gpg  -o /tmp/gpg.local  --passphrase cnic252 -d gpg.local

 

/tmp/gpg.local is readable. 

 

 

二、

since as3 doesn't support --passphrase, we use the following solution

 

gpg --batch --passphrase-fd 0 -o hh -d hello.gpg <a

 

The context of a is just the passwd. --batch means not query; -o is outfile;

 

--passphrase-fd n:

 

Read the passphrase from file descriptor n. If you use 0  for
                 n,  the  passphrase  will be read from stdin 

 

----------------------------------------------------------------------------

GPG常用参数:

语法:gpg [选项] [文件名]
签字、检查、加密或解密
默认的操作依输入数据而定

指令:

-s, –sign [文件名]           生成一份签字
–clearsign [文件名]      生成一份明文签字
-b, –detach-sign             生成一份分离的签字
-e, –encrypt                 加密数据
-c, –symmetric               仅使用对称加密
-d, –decrypt                 解密数据(默认)
–verify                  验证签字
–list-keys               列出密钥
–list-sigs               列出密钥和签字
–check-sigs              列出并检查密钥签字
–fingerprint             列出密钥和指纹
-K, –list-secret-keys        列出私钥
–gen-key                 生成一副新的密钥对
–delete-keys             从公钥钥匙环里删除密钥
–delete-secret-keys      从私钥钥匙环里删除密钥
–sign-key                为某把密钥添加签字
–lsign-key               为某把密钥添加本地签字
–edit-key                编辑某把密钥或为其添加签字
–gen-revoke              生成一份吊销证书
–export                  导出密钥
–send-keys               把密钥导出到某个公钥服务器上
–recv-keys               从公钥服务器上导入密钥
–search-keys             在公钥服务器上搜寻密钥
–refresh-keys            从公钥服务器更新所有的本地密钥
–import                  导入/合并密钥
–card-status             打印卡状态
–card-edit               更改卡上的数据
–change-pin              更改卡的 PIN
–update-trustdb          更新信任度数据库
–print-md 算法 [文件]    使用指定的散列算法打印报文散列值

选项:

-a, –armor                   输出经 ASCII 封装
-r, –recipient 某甲          为收件者“某甲”加密
-u, –local-user              使用这个用户标识来签字或解密
-z N                          设定压缩等级为 N (0 表示不压缩)
–textmode                使用标准的文本模式
-o, –output                  指定输出文件
-v, –verbose                 详细模式
-n, –dry-run                 不做任何改变
-i, –interactive             覆盖前先询问
–openpgp                 行为严格遵循 OpenPGP 定义
–pgp2                    生成与 PGP 2.x 兼容的报文

(请参考在线说明以获得所有命令和选项的完整清单)

范例:

-se -r Bob [文件名]          为 Bob 这个收件人签字及加密
–clearsign [文件名]         做出明文签字
–detach-sign [文件名]       做出分离式签字
–list-keys [某甲]           显示密钥
–fingerprint [某甲]         显示指纹

--------------------------------------------

GnuPGDotNet.zip

pgp,GnuPG 使用记录

开源工具:

http://www.gpg4win.org/

 

参考一:

gpg --export [--armor] # outfile 取出的公开钥匙至 outfile中。
gpg --import [keyfile] 将公开钥匙[keyfile]加入钥匙环中。
gpg -k 列印出公开钥匙。
gpg -e -r file 加密file至binary档file.gpg中。
gpg -e -r --armor file 加密file至ASCII档file.asc中。
gpg -s file 加签file至binary档file.gpg中。
gpg -s --armor file 加签file至ASCII档file.asc中。
gpg -se -r file 加密加签file至binary档file.gpg中。
gpg -se -r [-armor] file 加密加签file至ASCII档file.asc中。
gpg -v file 解密file。

GnuPGGNU Privacy GuardGPG)是一个以释出的开放源码用于或的,可用来取代。大多数gpg软件仅支持命令行方式,一般人较难掌握。由于gpg软件开放源代码,很难隐藏后门,因此比pgp等商业软件安全。

命令行

  gpg (GnuPG) 1.4.1
  Copyright (C) 2005 Free Software Foundation, Inc. This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the file COPYING for details.
  Home: D:/GNU/GnuPG
  支持的算法:
  公钥:RSA, RSA-E, RSA-S, ELG-E, DSA
  对称加密:3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH
  散列:MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512
  压缩:不压缩, ZIP, ZLIB, BZIP2
  语法:gpg [选项] [文件名]
  签字、检查、加密或解密
  默认的操作依输入数据而定
  指令:
  -s, --sign [文件名] 生成一份签字
  --clearsign [文件名] 生成一份明文签字
  -b, --detach-sign 生成一份分离的签字
  -e, --encrypt 加密数据
  -c, --symmetric 仅使用对称加密
  -d, --decrypt 解密数据(默认)
  --verify 验证签字
  --list-keys 列出密钥
  --list-sigs 列出密钥和签字
  --check-sigs 列出并检查密钥签字
  --fingerprint 列出密钥和指纹
  -K, --list-secret-keys 列出私钥
  --gen-key 生成一副新的密钥对
  --delete-keys 从公钥钥匙环里删除密钥
  --delete-secret-keys 从私钥钥匙环里删除密钥
  --sign-key 为某把密钥添加签字
  --lsign-key 为某把密钥添加本地签字
  --edit-key 编辑某把密钥或为其添加签字
  --gen-revoke 生成一份吊销证书
  --export 导出密钥
  --send-keys 把密钥导出到某个公钥服务器上
  --recv-keys 从公钥服务器上导入密钥
  --search-keys 在公钥服务器上搜寻密钥
  --refresh-keys 从公钥服务器更新所有的本地密钥
  --import 导入/合并密钥
  --card-status 打印卡状态
  --card-edit 更改卡上的数据
  --change-pin 更改卡的 PIN
  --update-trustdb 更新信任度数据库
  --print-md 算法 [文件] 使用指定的散列算法打印报文散列值
  选项:
  -a, --armor 输出经 ASCII 封装
  -r, --recipient 某甲 为收件者“某甲”加密
  -u, --local-user 使用这个用户标识来签字或解密
  -z N 设定压缩等级为 N (0 表示不压缩)
  --textmode 使用标准的文本模式
  -o, --output 指定输出文件
  -v, --verbose 详细模式
  -n, --dry-run 不做任何改变
  -i, --interactive 覆盖前先询问
  --openpgp 行为严格遵循 OpenPGP 定义
  --pgp2 生成与 PGP 2.x 兼容的报文
  (请参考在线说明以获得所有命令和选项的完整清单)
  范例
  -se -r Bob [file] 为Bob签名并加密(指定文件)
  --clearsign [file] 制作纯文本签名(指定文件)
  --detach-sign [file] 制作可分离的签名(指定文件)
  --list-keys [names] 显示密匙列表(指定用户名)
  --fingerprint [names] 显示指纹(指定用户名)
  修改密匙:
  --edit-key 密匙ID
  quit 退出本级菜单
  save 保存并退出
  help 显示本帮助
  fpr 显示密匙指纹
  list 列出密匙及用户ID
  uid 选择用户ID N
  key 选择子密匙 N
  check 检查签名
  sign 给选定用户ID的密匙签名
  lsign 给选定用户ID的密匙签名(本地签名,不可导出)
  tsign 给选定用户ID的密匙签名(用信任的签名)
  nrsign 给选定用户ID的密匙签名(用不可撤销的签名)
  adduid 添加用户ID
  addphoto 添加照片ID
  deluid 删除选定的用户ID
  addkey 添加子密匙
  addcardkey 添加密匙到智能卡
  keytocard 移动密匙到智能卡
  bkuptocard 移动备份密匙打智能卡
  delkey 删除选定的子密匙
  addrevoker 添加撤回密匙
  delsig 从选定的密匙中删除签名
  expire 更改(子)密匙有效期
  primary 标记选定的密匙为主密匙
  toggle 切换私匙和公匙列表
  pref 显示参数(高级)
  showpref 显示参数(详细)
  setpref 给选定的用户ID设置参数
  keyserver 设置密匙服务器
  passwd 更改密匙口令
  trust 更改信任级别
  revsig 撤销签名
  revuid 撤销用户ID
  revkey 撤销(子)密匙
  enable 启用密匙
  disable 禁用密匙
  showphoto 显示照片ID

注意事项:

  在导入密匙文件时,应注意密匙文件所在路径没有中文名称和空格,否则会出现出错提示,无法导入密匙。

参考:

官网:http://www.gnupg.org/

http://www.pgpi.org/download/

创建公钥和私钥

使用 PuttyGen 创建 openSSH 格式的公钥和私钥,步骤如下:

下载: http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

  1. 启动 PuttyGen。
  2. 当 Putty Key Generator 屏幕出现时,单击Generate开始生成新的公钥/私钥对:

    生成新公钥/私钥对
    点击查看原图

  3. 在高亮区域周围移动鼠标,直到进度条填满,生成密钥:

    创建一个密码
    点击查看原图

  4. 当公钥/私钥对生成之后,输入一个密码(比如 passw0rd):

    生成新的公钥/私钥对
    点击查看原图

  5. 选择公钥全部内容,粘贴到 OpenSSH authorized_keys 文件框中,然后右键单击并选择Copy

    选择公钥
    点击查看原图

  6. 打开一个新 Notepad 文档,将公钥粘贴在其中。公钥应该单独成行的,以 ssh-rsa 开头:

    新 Notepad 文档
    点击查看原图

  7. 保存公钥到与用户(userkey)同名的文件中,此文件是在 freeSSH 中配置的(下面将创建),在 freeSSHd 安装目录中没有扩展名。这种情况下,将文件另存为 c:\freesshd\userkey (您必须手动重命名该文件来删除扩展名):

    保存公钥
    点击查看原图

  8. 将公钥保存为 OpenSSH 格式:从 PuttyGen 菜单栏选择Conversions => Export OpenSSH key

    导出私钥
    点击查看原图

  9. 保存文件为 c:\userkeyprivate:

    保存私钥
    点击查看原图

  10. 关闭 PuttyGen。

用C#.NET调用Java开发的WebService传递int,double问题

用C#.NET调用Java开发的WebService时,先在客户端封装的带有int属性的对象,当将该对象传到服务器端时,服务器端可以得到string类型的属性值,却不能得到int类型、double和DateTime类型的值(在服务端得到的均为null) 解决办法: VS2005封装WebService引用

用C#.NET调用Java开发的WebService时,先在客户端封装的带有int属性的对象,当将该对象传到服务器端时,服务器端可以得到string类型的属性值,却不能得到int类型、double和DateTime类型的值(在服务端得到的均为null)

解决办法:

VS2005封装WebService引用时,如果WebService发布的是一个基本数据类型组成的对象,则会对该对象的非string属性同时生成两个属性,一般是这样的"属性××"、"属性××Specified"。而"属性名Specified"是一个bool类型,只有这个属性被设置成true时,"属性××"的值才会被序列化成xml传递。

同样的道理,用.NET提供WebService给JAVA调用时,如果是一个基本数据类型组成的对象,则会对该对象的非string属性同时生成两个属性,一般是这样的"属性××"、"属性××Specified"。如果不将“属性××Specified”设置为true的话,服务端得到的数据将是null。解决办法就是把“属性××Specified”设置为true或者把“属性××Specified”删掉。

资料:http://msdn.microsoft.com/zh-cn/library/system.xml.xmlattribute.specified(VS.80).aspx

.NET Framework 类库

XmlAttribute.Specified 属性

获取一个值,该值指示是否显式设置了属性值。

命名空间:System.Xml

程序集:System.Xml(在 system.xml.dll 中)

属性值

如果在原始实例文档中显式地为该属性给定一个值,则为 true;否则为 false。false 值指示该属性的值来自 DTD。

备注

该属性是由实现负责的,而不是用户。如果用户更改该属性的值(即使它最后与默认/固定值具有相同的值),Specified 标志就会自动转为 true。若要重新将该属性指定为 DTD 中的默认/固定值,则用户必须删除该属性。然后,实现提供一个新属性,其 Specified 设置为 false,并具有默认/固定值(如果存在的话)。

摘要:

如果属性具有文档中的分配值,则 Specified 为 true,并且该值是分配值。

如果属性没有文档中的分配值,而具有 DTD 中的默认/固定值,则 Specified 为 false,该值是 DTD 中的默认/固定值。

否则,该属性不出现在文档的结构模型中。