php操作mysql的类,支持读写分离。
代码:
<?php
/**
* MySQL读写分离类
* $db_config = array(
* 'master' => array('host'=>'localhost:3306','user'=>'admin','passwd'=>'123456','db'=>'stat'),
* 'slave' => array(
* array('host'=>'localhost:3307','user'=>'admin','passwd'=>'123456','db'=>'stat'),
* array('host'=>'localhost:3308','user'=>'admin','passwd'=>'123456','db'=>'stat')
* )
* );
*
* 注释:如果slave有多个时随机连接其中的一个
* 最后编辑:www.
*/
/*
$db_config = array(
'master' => array('host'=>'localhost:3306','user'=>'admin','passwd'=>'123456','db'=>'stat'),
'slave' => array(
array('host'=>'localhost:3307','user'=>'admin','passwd'=>'123456','db'=>'stat'),
array('host'=>'localhost:3308','user'=>'admin','passwd'=>'123456','db'=>'stat')
)
);
$db = MySQL::getInstance('','r-w');
$sql = "select * from admin";
$rs = $db->query($sql);
while ($row = $db->fetch($rs)){
echo "uid:".$row['uid']." ".$row['userName']."<br />";
}
echo "<hr />";
*/
class MySQL
{
private static $_instance = null;//数据库连接实例
private static $_master = null;//主数据库连接实例
private static $_slave = null;//重数据库连接实例
public $_config = array();//数据库连接配置信息
public $_res = null;//查询实例句柄
public $_flag = '';//标识当前语句是在主还是重数据库上执行
public $_link = null;
/**
* 单实例
* Enter description here ...
* @param unknown_type $dbname
* @param unknown_type $mode
*/
public static function & getInstance($dbname='',$mode='rw'){
if (is_null(self::$_instance)){
self::$_instance = new self();
self::$_instance->__getConf();
self::$_instance->connect($dbname,$mode);
}
return self::$_instance;
}
/**
* 获取数据库配置信息
* Enter description here ...
*/
public function __getConf(){
global $db_config;
$this->_config['master'] = $db_config['master'];
$this->_config['slave'] = $db_config['slave'];
}
/**
* 数据库连接
* Enter description here ...
* @param $dbname 指定连接的数据库名,默认情况下连接配置文件的库
* @param $mode rw表示连接主库,r-w表示读写分离
*/
public function connect($dbname='',$mode = 'rw'){
if($mode == 'rw'){
if(is_null(self::$_master)){
$this->_master = $this->_slave = $this->conn_master($dbname);
}
}else{
if(is_null(self::$_master)){
$this->_master = $this->conn_master($dbname);
}
if(is_null(self::$_slave)){
$this->_slave = $this->conn_slave($dbname);
}
}
}
/**
* 连接到主数据库服务器
* Enter description here ...
*/
public function conn_master($dbname=''){
$_link = mysql_connect()($this->_config['master']['host'],$this->_config['master']['user'],$this->_config['master']['passwd'],true) or die ("Connect ".$this->_config['master']['host']." fail.");
mysql_select_db(empty($dbname)?$this->_config['master']['db']:$dbname,$_link) or die(" The DB name ".$this->_config['master']['db']." is not exists.");
mysql_query()("set names utf8",$_link);
return $_link;
}
/**
* 连接到从数据库服务器
* Enter description here ...
*/
public function conn_slave($dbname=''){
$offset = rand(0,count($this->_config['slave'])-1);
$_link = @mysql_connect($this->_config['slave'][$offset]['host'],$this->_config['slave'][$offset]['user'],$this->_config['slave'][$offset]['passwd'],true) or die(" Connect ".$this->_config['slave'][$offset]['host']." fail.");
mysql_select_db(empty($dbname)?$this->_config['slave'][$offset]['db']:$dbname,$_link) or die(" The DB name ".$this->_config['slave'][$offset]['db']." is not exists.");
mysql_query("set names utf8",$_link);
return $_link;
}
/**
* 执行数据库查询
* Enter description here ...
* @param string $sql
*/
public function query($sql,$master=true){
if($master == true || (substr(strtolower()($sql),0,6) != 'select') && $master == false){
$this->_res = mysql_query($sql,$this->_master);
if(!$this->_res){
$this->_error[] = mysql_error($this->_master);
}
$this->_flag = 'master';
$this->_link = $this->_master;
} else {
$this->_res = mysql_query($sql,$this->_slave);
if(!$this->_res){
$this->_error[] = mysql_error($this->_slave);
}
$this->_flag = 'slave';
$this->_link = $this->_slave;
}
return $this->_res;
}
/**
* 获取单行记录
* Enter description here ...
* @param mixed $rs
*/
public function get($rs=''){
if(empty($rs)){
$rs = $this->_res;
}
return mysql_fetch_row($rs);
}
/**
* 获取多行记录
* Enter description here ...
* @param mixed $rs
* @param $result_type
*/
public function fetch($rs = ''){
if(empty($rs)){
$rs = $this->_res;
}
return mysql_fetch_array($rs,MYSQL_ASSOC);
}
/**
* 插入数据
* Enter description here ...
* @param unknown_type $sql
*/
public function add($sql){
$rs = $this->query($sql);
if($rs)
return mysql_insert_id($this->_link);
return false;
}
/**
* 更新数据
* Enter description here ...
* @param unknown_type $sql
*/
public function update($sql){
if(empty($sql)) return false;
$rs = $this->query($sql);
if($rs)
return $this->fetchNum();
return false;
}
/**
* 获取上一条语句影响的行数
* Enter description here ...
*/
public function fetchNum(){
return mysql_affected_rows($this->_link);
}
/**
* 析构函数,释放数据库连接资源
* Enter description here ...
*/
public function __destruct(){
mysql_close($this->_link);
}
}
说明:
伪静态url,还是建议在nginx、apache、iis中用模块来实现。
不推荐使用php编程实现。
一,url的静态化原理
1,把动态的url转换成静态的url,转换方法是统一的接口。把静态的url放到html中,这样通过页面看到的就是静态的url。
2,apache或其他,加载rewrite模块,添加重写规则。这样当点页面中的静态url时,就可以转向正确的url了。
虽然执行的还是php文件,但是浏览器的地址栏中显示出来的,还是静态的url。
如果用php来实现url静态化,也要保持地址栏里面也要静态的url。
二,把动态url转换成静态url
<?php
//将url转换成静态url
function url_rewrite($file, $params = array (), $html = "", $rewrite = true) {
if ($rewrite) { //开发阶段是不要rewrite,所在开发的时候,把$rewrite = false
$url = ($file == 'index') ? '' : '/' . $file;
if (! empty ( $params ) && is_array ( $params )) {
$url .= '/' . implode ( '/', array_slice($params, 0 , 2));
$param = array_slice($params, 2);
foreach($param as $key => $value){
$url .= '/' . $key . '/' . urlencode ( $value );
}
}
if (! empty ( $html )) {
$url .= '.' . $html;
}
} else {
$url = ($file == 'index') ? '/' : '/' . $file;
if (substr ( $url, - 4 ) != '.php' && $file != 'index') {
$url .= '.php';
}
if (! empty ( $params ) && is_array ( $params )) {
$url .= '?' . http_build_query ( $params );
}
}
return $url;
}
echo url_rewrite ( 'test', array ('class' => "User", 'act' => 'check', 'name' => 'tank','page'=>5 ) );echo "<br/>";
//$rewrite = false的情况下,显示如下/test.php?class=User&act=check&name=tank
echo url_rewrite ( 'test.php', array ('class' => "User", 'act' => 'check', 'name' => 'tank' ) );echo "<br/>";
//$rewrite = true的情况下,显示如下/test.php/User/check/tank
echo url_rewrite ( 'test', array ('class' => "User", 'act' => 'check', 'name' => 'tank' ) );echo "<br/>";
//$rewrite = true的情况下,显示如下/test/User/check/tank
echo url_rewrite ( 'test', array ('class' => "User", 'act' => 'check', 'name' => 'tank' ), 'html' );echo "<br/>";
//$rewrite = true的情况下,显示如下/test/User/check/tank.html
?>
<a href="/blog_article/test3</php echo url_rewrite(.html'test.php',array('class'=>"User",'act'=>'check','name'=>'tank'));?>">test</a>
以上把动态url转换成静态的url,页面中会产生链接如下:
<a href="/blog_article/test3/test.php/User/check/name/tank/index.html">test</a>
此时如果直接点击的话,肯定会报404错误的,因为根不可能找到tank这个目录的。
需要要把找不到的目录和文件指定一个php文件。这个需要用到apache,nginx,或htaccess等。
三,指定一个统一入口
RewriteCond %{REQUEST_FILENAME} !-d //打不到目录
RewriteRule . /test3/index.php [L]
代码说明:
如果找不到目录转到index.php文件,如果找不到文件,也转到index.php。
当访问http://localhost/test3/test.php/User/check/tank时候,就会转到index.php。
以下内容都是以http://localhost/test3/test.php/User/check/tank这种重写的方式来操作的。
四,index.php文件
$filename = $_SERVER['REQUEST_URI']; //请求的url
/**请求的url,"/test3/test.php/User/check/tank"
* test.php 要去的php文件
* User 是class名
* check 是class中的方法名
* tank 是要传到check的参数
* by www.
*/
preg_match("/(\w+\.php)/",$filename,$match); //查找php文件名
$array = explode()('/',$filename); //将静态url进行分割
$key = array_keys()($array,$match[0]); //得到文件所对应的下标Array ( [0] => 2 )
$file_array = array_slice($array,0,$key[0]+1); //Array ( [0] => [1] => test3 [2] => test.php )
$param_array = array_slice($array,$key[0]+1); //Array ( [0] => User [1] => check [2] => tank )
$file_path = implode('/',$file_array);
if($array[$key[0]] != "index.php"){
include_once($array[$key[0]]); //包函请求url中的php文件,在这里是test.php
}
if(class_exists($param_array[0])){ //判断一下test.php这个文件中有没有User这个class
$obj = new $param_array[0];
if(method_exists($obj,$param_array[1])){ //判断一下User这个class中有有没有check这个方法
$obj->$param_array[1]($param_array[3]); //调用这个方法,结果是(我的名子叫tank)
}
}
?>
五,test.php文件
class User {
public function check($name){
echo "我的名子叫".$name;
}
}
?>
至此,当访问http://localhost/test3/test.php/User/check/tank时,就不会报错了。
php实现登录次数超过5次,就冻结用户。
冻结用户的标志列为:blocked=1。
代码:
/**
* 多次登录失败,冻结账号
* by www.
*/
if (!isset()($_SESSION['AttemptsCounter'])){
$_SESSION['AttemptsCounter'] = 0;
}
if (!isset($AllowAnyone)){ /* only do security checks if AllowAnyone is not true */
if (!isset($_SESSION['AccessLevel']) OR $_SESSION['AccessLevel'] == '' OR
(isset($_POST['UserNameEntryField']) AND $_POST['UserNameEntryField'] != '')) {
/* if not logged in */
$_SESSION['AttemptsCounter']++;
// Show login screen
if (!isset($_POST['UserNameEntryField']) or $_POST['UserNameEntryField'] == '') {
include('includes/Login.php');
exit;
}
$sql = "SELECT www_users.*
FROM www_users
WHERE www_users.userid='" . $_POST['UserNameEntryField'] . "'
AND (www_users.password='" . CryptPass($_POST['Password']) . "'
OR www_users.password='" . $_POST['Password'] . "')";
$Auth_Result = DB_query($sql, $db);
// Populate session variables with data base results
if (DB_num_rows($Auth_Result) > 0) {
exit;
} else { // Incorrect password
// 5 login attempts, show failed login screen
if (!isset($_SESSION['AttemptsCounter'])) {
$_SESSION['AttemptsCounter'] = 0;
} elseif ($_SESSION['AttemptsCounter'] >= 5 AND isset($_POST['UserNameEntryField'])) {
/*User blocked from future accesses until sysadmin releases */
$sql = "UPDATE www_users SET blocked=1 WHERE www_users.userid='" . $_POST['UserNameEntryField'] . "'";
$Auth_Result = DB_query($sql, $db);
die(include('includes/FailedLogin.php'));
}
$demo_text = '<FONT SIZE="3" COLOR="red"><b>' . _('incorrect password') . '</B></FONT><BR><B>' . _('The user/password combination') . '<BR>' . _('is not a valid user of the system') . '</B>';
die(include('includes/Login.php'));
}
} // End of userid/password check
} /* only do security checks if AllowAnyone is not true */
function CryptPass( $Password ) {
global $CryptFunction;
if ( $CryptFunction == 'sha1' ) {
return sha1($Password);
} elseif ( $CryptFunction == 'md5' ) {
return md5($Password);
} else {
return $Password;
}
}
?>