Archive for the ‘ 程序开发 ’ Category

pdo的使用

PHP 5.1 发布时附带一个全新的数据库连接层PDO(PHP Data Objects)。它与ADODB和Pear DB等数据库抽象层不同,它提供的是如何存取数据库和处理查询结果,效率也更高,还可以通过预处理语句来防止sql注入。
目前支持的数据库:
• DBLIB: FreeTDS / Microsoft SQL Server / Sybase
• Firebird (http://firebird.sourceforge.net/): Firebird/Interbase 6
• MYSQL (http://www.mysql.com/): MySQL 3.x/4.x
• OCI (http://www.oracle.com): Oracle Call Interface
• ODBC: ODBC v3 (IBM DB2 and unixODBC)
• PGSQL (http://www.postgresql.org/): PostgreSQL
• SQLITE (http://www.postgresql.org/): SQLite 3 and SQLite 2
1. 连接数据库
PDO提供了统一的接口:PDO对象。
$db=new PDO(
“driver_name:dbname=db_name;host=hostname/IP;[charset=char_type]“,   //(1)连接字符串
“db_username”,  //(2)db用户名
“db_password”   //(3)db密码
);
说明,PDO有三个参数
(1)连接字符串:
driver_name是使用的PDO驱动,可以为:mysql, mssql, sybase, dblib, firebird, oci, odbc, pgsql, sqlite, sqlite2;
db_name是数据库名称;
hostname/IP是指要连接到哪里,如果是本地则为localhost。
[charset=char_type]是可选的,用来设置字符类型。
(2)db用户名
(3)db密码
example:
$db = new PDO(
“pgsql:dbname=pdo;host=localhost;charset=utf-8″,
“postgres8″,
“postgres8″
);
echo “Successfully created a PDO object”;
?>
连接之前,应先确认已经加载了PDO模块。如果试图处理一个无效的连接字符串:
$db = new PDO(
“this_is_not_a_pdo_module:dbname=pdo;host=localhost”,
“foo”,
“bar”
);
echo “Successfully created a PDO object”;
?>
PHP将会返回以下错误:
Fatal error: Uncaught exception ‘PDOException’ with message ‘could not find driver’
所以,我们可以用一种优雅的方式来处理,即抛出PDO异常来处理错误(但并不是所有情况都是)。
try
{
$db = new PDO(
“this_is_not_a_pdo_modul:dbname=pdo;host=localhost”,
“postgres8″,
“postgres8″
);
}
catch( PDOException $e )
{
die( $e->getMessage() );
}
echo “Successfully created a PDO object”;
?>
我们会得到
could not find driver

SQLSTATE[HY000] [7] FATAL: database “pdo2″ does not exist
如果数据库不存在(不同的错误会返回不同的提示信息)。
2. 设置属性
1) PDO有三种错误处理方式:
• PDO::ERRMODE_SILENT不显示错误信息,只设置错误码
• PDO::ERRMODE_WARNING显示警告错
• PDO::ERRMODE_EXCEPTION抛出异常
可通过以下语句来设置错误处理方式为抛出异常
$db->setAttribute(PDO::ATTR_ERRMODE, );
example:
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
当设置为PDO::ERRMODE_SILENT时可以通过调用errorCode() 或errorInfo()来获得错误信息,当然其他情
况下也可以。
2) 因为不同数据库对返回的字段名称大小写处理不同,所以PDO提供了PDO::ATTR_CASE设置项(包括
PDO::CASE_LOWER,PDO::CASE_NATURAL,PDO::CASE_UPPER),来确定返回的字段名称的大小写。
3) 通过设置PDO::ATTR_ORACLE_NULLS类型(包括PDO::NULL_NATURAL,PDO::NULL_EMPTY_STRING,
PDO::NULL_TO_STRING)来指定数据库返回的NULL值在php中对应的数值。
3. 查询
为了说明清楚,我们这里定义了一个RSS feeds表
id integer
name character varying(100)
url varharacter varying(255)
feed character varying(255)
不使用预处理语句的方式:
$stmt=$db->query(“select * from feeds”);
while($f=$stmt->fetch()){
echo $f["id"].” “;
echo $f["name"].” “;
echo $f["url"].” “;
echo $f["feed"].”
“;
};
/*使用foreach 获取数据
foreach( $db->query( “SELECT * FROM feeds” ) as $row )
{
print_r( $row );
}
*/
?>
得到以下结果:
Array
(
[id] => 1
[0] => 1
[name] => Planet-PHP
[1] => Planet-PHP
[url] => http://www.planet-php.net
[2] => http://www.planet-php.net
[feed] => http://www.planet-php.net/rdf/
[3] => http://www.planet-php.net/rdf/
)
(只显示已行为了节省空间)
使用预处理语句的方式:
$stmt = $db->prepare( “SELECT * FROM feeds” );
$stmt->execute();
print_r( $stmt->fetch() );
?>
这里,$stmt是一个PDOStatement对象,预处理之后会得到这样一个对象,必须execute后才起作用。
fetch函数只提取了一行数据,如果需要读取全部数据,可换成fetchAll函数。
绑定数据
$stmt = $db->prepare( “SELECT * FROM feeds WHERE url = :url” );
$url = “http://www.planet-php.net”;
$stmt->bindParam( “:url”, $url );
$stmt->execute();
while( $row = $stmt->fetch() )
{
print_r( $row );
}
?>
这里,bindParam将$url变量绑定到了:url域,执行时会自动将改变量载入。
插入数据
$stmt = $db->prepare(
“INSERT INTO feeds
( name, url, feed )
VALUES
( :name, :url, :feed )”
);
$stmt->execute(
array(
“:name” => “Planeti Apache”,
“:url” => “http://www.planetapache.org”,
“:feed” => “http://www.planetapache.org/rss10.xml”
)
);
?>
实现插入数据也可以像绑定数据一样来quote数据,这里给出通过在execute中给定输入参数来自动quote
的方法。
事务处理
$dbh->beginTransaction();
try {
$dbh->query(“UPDATE …”);
$dbh->query(“UPDATE …”);
$dbh->commit();
} catch (Exception $e) {
$dbh->rollBack();
}
如果数据库支持事务处理,调用beginTransaction的同时将数据库设置为非自动提交,commit或rollBack
返回自动提交状态。
4. 存储过程
$stmt = $dbh->prepare(“CALL sp_set_string(?)”);
$stmt->bindParam(1, $str);
$str = ‘foo’;
$stmt->execute();
于先前的例子差不多,只是这里使用了“?”数据绑定方法,sp_set_string是存储过程名称。
带有输出参数的存储过程
$stmt = $dbh->prepare(“CALL sp_get_string(?)”);
$stmt->bindParam(1, $ret,PDO:ARAM_STR, 4000);
if ($stmt->execute()) {
echo “Got $ret\n”;
}
绑定列输出
$stmt = $dbh->prepare(“SELECT extension, name from CREDITS”);
if ($stmt->execute()) {
$stmt->bindColumn(‘extension’, $extension);
$stmt->bindColumn(‘name’, $name);
while ($stmt->fetch(PDO::FETCH_BOUND)) {
echo “Extension: $extension\n”;
echo “Author: $name\n”;
}
}

Restriction of the access with the help of Nginx

In this short post the point is how to protect your files and some part of your web site with a user password. With Nginx, a lot of options exist to protect your site with usernames and passwords. In Nginx the solution is not less attractive than in apache.

In the configuration file, set folder to close, it is only necessary to load the file with passwords.
There are two examples for closing of the folder with files:
location ^~ /files/ {
root   /path/to/server;
autoindex    on;
autoindex_exact_size  off;
auth_basic “Hello, please login”;
auth_basic_user_file /usr/nginx/passwords;
access_log   /usr/nginx/logs/files.log   download;
}
and for closing of the admin-folder with the additional restriction on IP:
location ^~ /admin/ {
fastcgi_pass unix:/home/project/server.sock;
include  conf/fastcgi.conf;
allow 11.11.0.0/16;
allow 22.22.22.22;
deny all;
auth_basic “Hello, Admin, please login”;
auth_basic_user_file /usr/nginx/adminpassword;
access_log   /usr/nginx/logs/admin.log  main;
}
The passwd program utility of Apache can be used to create and update usernames and passwords of new users:
htpasswd -b passwords NewUser NewPassword
In the file the writing with the encoded password looks like:
NewUser:P47ghZ4kloG78: Your Can Comment Here
The protection from cracking the password can be organized at the same time with two methods based on the use iptables:
Blocking IP temporarily if the amount of the requests per second exceeds any reasonable amount.
Write failed attempts in the log, check it with the script every minute, than pumps the IP addresses in iptables
For the first variant it is enough to create rules:
iptables -A INPUT -p tcp –syn –dport 80 -i eth0 -m state –state NEW
-m recent –name bhttp –set
iptables -A INPUT -p tcp –syn –dport 80 -i eth0 -m state –state NEW
-m recent –name bhttp –update –seconds 120
–hitcount 360 -j DROP
iptables -A INPUT -p tcp –syn –dport 80 -i eth0 -j ACCEPT
It is possible to use TARPIT instead of DROP to complicate the life of the crackers.

For the second variant it is necessary to add in config:
location /401.html {
root   /usr/nginx;
access_log   /usr/nginx/logs/denied.log  error401;
}
For example the format error 401 looks at me:
log_format error401  ‘$remote_addr – $remote_user [$time_local] ‘
‘$status “$request”‘;
Now all wrong logins are saved in a separate log file, which is checked per cron job:
*/1 * * * * root /usr/nginx/parser401.pl >/dev/null 2>&1
For example this script: parser401.pl Скрипт проверяет лог, и если обнаруживает больше 4-х попыток неправильного набора пароля, блокирует этот IP. Script checks the log file and if it finds more than 4 attempts of the wrong password, it blocks this IP address.
Are there any ideas?

htpasswd – 管理用于基本认证的用户文件

htpasswd建立和更新用于基本认证的存储用户名/密码的文本文件。如果htpasswd不能读写此文件,它返回一个出错代码,而不做任何修改。
服务器上的资源可以被限制为仅允许由htpasswd建立的文件中的用户所访问。此程序只能管理存储在文本文件中的用户名和密码,但是它可以加密并显示密码信息,从而可以为其他数据存储类型所利用。要使用DBM数据库,请参见dbmmanage 。

htpasswd使用专为Apache作了修改的MD5算法或系统函数crypt()加密密码。htpasswd所管理的文件可以包含两种类型的密码;有些用户的密码使用MD5加密的,而同一个文件中的其他用户密码则使用crypt()加密。

本文章仅列出命令行参数,配置基本认证的相关指令的细节请参见mod_auth_basic文档。

语法
htpasswd [ -c ] [ -m ] [ -D ] passwdfile username
htpasswd -b [ -c ] [ -m | -d | -p | -s ] [ -D ] passwdfile username password
htpasswd -n [ -m | -d | -s | -p ] username
htpasswd -nb [ -m | -d | -s | -p ] username password

选项
-b
使用批处理方式。也就是直接从命令行获取密码而不进行提醒。使用这个选项需要特别注意,因为命令行中的密码是清晰可见的。
-c
创建passwdfile文件。如果passwdfile已经存在,那么将被清空并改写。该选项不能和 -n 同时使用。
-n
在标准输出上显示结果而不是更新文件。用于生成可以为Apache非文本输出存储格式所接受的密码记录。这个选项改变了命令行语法,因为passwdfile参数(通常是第一个)被忽略了。该选项不能和 -c 同时使用。
-m
使用MD5加密密码。在Windows, Netware, TPF上这是默认方法。
-d
使用crypt()对密码进行加密。在Windows, Netware, TPF以外的平台上这是默认方法。虽然有可能在所有的平台上被htpasswd支持,但是在Windows, Netware, TPF上,该方法不能被httpd所支持。
-s
使用 SHA 对密码进行加密。这种方法易于通过LDAP目录交换格式和Netscape server进行交换。
-p
使用明文密码(不加密)。虽然htpasswd在所有平台上都支持这种方法,但是httpd只能在Windows, Netware, TPF上支持这种方法。
-D
如果username存在于passwdfile中,则删除该用户。
passwdfile
包含用户名和密码的文本文件的名称。如果使用了 -c 选项,若文件已存在则更新它,若不存在则创建它。
username
在passwdfile中添加或更新记录。若username不存在则添加一条记录,若存在则更新其密码。
password
将被加密并存储到文件中的明文密码。必须和 -b 同时使用。

示例
htpasswd /usr/local/etc/apache/.htpasswd-users jsmith
添加或修改用户jsmith的密码。密码将被提示输入。在Windows平台上,密码将使用Apache修改过的MD5算法进行加密;在其它平台上将使用crypt()进行加密。如果指定的文件不存在,htpasswd将只返回一个错误代码,而不做其它任何事。
htpasswd -c /home/doe/public_html/.htpasswd jane
创建一个新文件并在其中添加一条用户jane的记录。密码将被提示输入。如果文件存在但是不能被读取或写入,则不会有任何记录被修改,同时htpasswd将会显示一个错误信息并返回一个错误代码。
htpasswd -mb /usr/web/.htpasswd-all jones Pwd4Steve
将来自命令行的密码(Pwd4Steve)使用MD5算法加密,并将其存入指定的文件。

安全方面的考虑
Web密码文件(比如由htpasswd管理)不应当存在于网络空间中,即不能被客户端有机会访问。
我们反对使用 -b 选项,因为密码将以明文的形式出现在命令行中。

限制
在Windows和MPE平台上,用htdbm加密的密码最大长度是255字符。超出部分将被截断。
htdbm使用的MD5加密算法已经被Apache修改过了,仅能够被Apache识别,不能被其它Web服务器识别。
用户最大长度是255字节,并且不能包含冒号(:)。

维尼半岁靓照!

我现在正处于青春期中,有那么一点点丑啦,您要做好心理准备哦~

我现在正处于青春期中,有那么一点点丑啦,您要做好心理准备哦~

哈哈哈哈 我就是维尼~

哈哈哈哈 我就是维尼~

咦?老爸你在干嘛?

咦?老爸你在干嘛?

可爱的维尼~_~2月大

2个月大时的维尼~,胖胖滴像个小熊,呵呵
Hi~我是维尼~

Hi~我是维尼~

“呵呵,看我老实,其实俺是名副其实的破坏大王~!”

“呵呵,看我老实,其实俺是名副其实的破坏大王~!”

我漂亮吧~可惜我只有个忙碌的老爸,不然我可以更漂亮!我可是个美少女哦!!!

我漂亮吧~可惜我只有个忙碌的老爸,不然我可以更漂亮!我可是个美少女哦!!!