康盛的 authcode 函数可以说对中国的PHP界作出了重大贡献。包括康盛自己的产品,以及大部分中国使用PHP的公司都用这个函数进行加密,authcode 是使用异或运算进行加密和解密。
原理如下,假如:
加密
明文:1010 1001
密匙:1110 0011
密文:0100 1010
得出密文0100 1010,解密之需和密匙异或下就可以了
解密
密文:0100 1010
密匙:1110 0011
明文:1010 1001
并没有什么高深的算法,密匙重要性很高,所以,关键在于怎么生成密匙。
那我们一起看下康盛的authcode怎么做的吧
// 参数解释
// $string: 明文 或 密文
// $operation:DECODE表示解密,其它表示加密
// $key: 密匙
// $expiry:密文有效期
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
// 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙
$ckey_length = 4;
// 密匙
$key = md5($key ? $key : $GLOBALS['discuz_auth_key']);
// 密匙a会参与加解密
$keya = md5(substr($key, 0, 16));
// 密匙b会用来做数据完整性验证
$keyb = md5(substr($key, 16, 16));
// 密匙c用于变化生成的密文
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length):
substr(md5(microtime()), -$ckey_length)) : '';
// 参与运算的密匙
$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);
// 明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存$keyb(密匙b),解密时会通过这个密匙验证数据完整性
// 如果是解码的话,会从第$ckey_length位开始,因为密文前$ckey_length位保存 动态密匙,以保证解密正确
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) :
sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
$string_length = strlen($string);
$result = '';
$box = range(0, 255);
$rndkey = array();
// 产生密匙簿
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
// 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度
for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
// 核心加解密部分
for($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
// 从密匙簿得出密匙进行异或,再转成字符
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}
if($operation == 'DECODE') {
// substr($result, 0, 10) == 0 验证数据有效性
// substr($result, 0, 10) - time() > 0 验证数据有效性
// substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16) 验证数据完整性
// 验证数据有效性,请看未加密明文的格式
if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) &&
substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
} else {
// 把动态密匙保存在密文里,这也是为什么同样的明文,生产不同密文后能解密的原因
// 因为加密后的密文可能是一些特殊字符,复制过程可能会丢失,所以用base64编码
return $keyc.str_replace('=', '', base64_encode($result));
}
}
1.主要文件,访问该页面,该页面根据“验证页面”的返回结果设置本文件的返回状态 header('HTTP/1.1 '.$code.' '.$_status[$code])
<?php
ini_set('max_execution_time', 120);
include("CheckConfig.php");
function send_http_status($code) {
static $_status = array(
// Informational 1xx
=> 'Continue',
=> 'Switching Protocols',
// Success 2xx
=> 'OK',
=> 'Created',
=> 'Accepted',
=> 'Non-Authoritative Information',
=> 'No Content',
=> 'Reset Content',
=> 'Partial Content',
// Redirection 3xx
=> 'Multiple Choices',
=> 'Moved Permanently',
=> 'Moved Temporarily ', // 1.1
=> 'See Other',
=> 'Not Modified',
=> 'Use Proxy',
// 306 is deprecated but reserved
=> 'Temporary Redirect',
// Client Error 4xx
=> 'Bad Request',
=> 'Unauthorized',
=> 'Payment Required',
=> 'Forbidden',
=> 'Not Found',
=> 'Method Not Allowed',
=> 'Not Acceptable',
=> 'Proxy Authentication Required',
=> 'Request Timeout',
=> 'Conflict',
=> 'Gone',
=> 'Length Required',
=> 'Precondition Failed',
=> 'Request Entity Too Large',
=> 'Request-URI Too Long',
=> 'Unsupported Media Type',
=> 'Requested Range Not Satisfiable',
=> 'Expectation Failed',
// Server Error 5xx
=> 'Internal Server Error',
=> 'Not Implemented',
=> 'Bad Gateway',
=> 'Service Unavailable',
=> 'Gateway Timeout',
=> 'HTTP Version Not Supported',
=> 'Bandwidth Limit Exceeded'
);
if(array_key_exists($code,$_status)) {
header('HTTP/1.1 '.$code.' '.$_status[$code]);
}
}
function GetStatusCode($url)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url); //设置URL
curl_setopt($curl, CURLOPT_HEADER, 1); //获取Header
curl_setopt($curl,CURLOPT_NOBODY,true); //Body就不要了吧,我们只是需要Head
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); //数据存到成字符串吧,别给我直接输出到屏幕了
$data = curl_exec($curl); //开始执行啦~
$HttpCode =curl_getinfo($curl,CURLINFO_HTTP_CODE); //我知道HTTPSTAT码哦~
curl_close($curl); //用完记得关掉他
return $HttpCode;
}
function ResetUrl(/blog_article/$url/index.html)
{
if(strpos($url,"?")>0)
$url.="&rnd";
else
$url.="?rnd";
$url.=rand();
return $url;
}
function ShowStateInfo($UrlArr,$MailPara)
{
$count=count($UrlArr);
if(isset($_REQUEST["start"]))
{
$start=$_REQUEST["start"]*1;
}
else
{
$start=1;
}
if(isset($_REQUEST["end"]))
{
$end=$_REQUEST["end"]*1;
}
else
{
$end=$start;
}
$start=$start-1;
$end=$end-1;
if($start<0)
{
$start=0;
}
if($start>=0 && $start<$count)
{
if($end>=$count)
{
$end=$count-1;
}
if($end<$start)
{
$end=$start;
}
$sTime=date("Y/m/d H:m:s");
echo "开始时间".$sTime."<br/>";
echo "检测结果<br />";
for($i=$start;$i<=$end;$i++)
{
$url=ResetUrl(/blog_article/$UrlArr[$i]/index.html);
$state=GetStatusCode($url);
echo " ".$state ." => <a href='http://".$url."' target='_blank'>".$url."<a>";
if($state!="200")
{
echo " <span >本条访问出错!</span><br/>";
send_http_status($state);
//发邮件
require("Mail.php");
$MailPara["Subject"]="网站监控结果";
$MailPara["Body"]="错误信息:状态-><span >".$state."</span><br/>地址:".$url;
SendResultMail($MailPara);
break;
}
echo "<br/>";
}
$eTime=date("Y/m/d H:m:s");
echo "结束时间".$eTime."<br/>";
}
}
ShowStateInfo($UrlArr,$MailPara);
?>
2.邮件
function SendResultMail($MailPara)
{
require("phpmailer/class.phpmailer.php");
$mail = new PHPMailer();
$mail->CharSet = $MailPara["CharSet"];
$mail->IsSMTP();
$mail->Host = $MailPara["Host"];
$mail->Port = $MailPara["Port"];
$mail->SMTPAuth = true;
$mail->Username = $MailPara["FromMail"];
$mail->Password = $MailPara["FromMailPassword"];
$mail->From = $MailPara["FromMail"];
$mail->FromName = $MailPara["FromMailName"];
foreach($MailPara["To"] as $toMail)
{
$mail->AddAddress($toMail["ToMail"], $toMail["ToMailName"]);
}
$mail->Subject = $MailPara["Subject"];
$mail->Body = $MailPara["Body"];
$mail->AltBody = $MailPara["AltBody"];
if(!$mail->Send())
{
echo "邮件发送失败. <p>";
echo "错误原因: " . $mail->ErrorInfo ."<br/>";
exit;
}
echo "邮件发送成功<br/>";
}
3.配置文件
<?php
$UrlArr=array(
"localhost/test/281892.shtml",
"localhost/test/all-229-1-221.shtml",
"localhost/testclass/all-254-1-1.shtml",
"localhost/test/cheng/bd/1988478.html",
"localhost/test/asd/2066495.html"
);
//邮箱发送相关信息
$MailPara=array(
"CharSet"=> "GB2312",
"Host"=> "smtp.exmail.qq.com", // 邮箱服务地址
"Port"=>25,
"FromMail"=> "fdsafdsafd@fdasfds.com", // 发件人邮箱地址
"FromMailPassword"=> "*********", // 发件人邮箱密码
"FromMailName"=> "检测", //发件人称呼
"To"=>array(
array(
"ToMail"=>"defdafdsafdsafdf@qq.com", //收件人邮箱地址
"ToMailName"=> "bqq", //收件人称呼
),
array(
"ToMail"=>"abfdsafdsafdsafc@gmail.com", //收件人邮箱地址
"ToMailName"=> "agmail", //收件人称呼
)
),
"Subject"=> "", //邮件标题
"Body"=> "", //邮件内容
"AltBody"=> "附加信息" //附加信息,可以省略
);
?>
邮件主要使用"phpmailer",点击下载
define("MYSQL_OPEN_LOGS",true);
class mysqliHelp
{
private $db;
public function __construct()
{
//如果要查询日志log的话,怎么办
}
public function __get($name )
{
//echo "__GET:",$name;
if(in_array($name,array("db"),true))//或者isset($this->$name)
return $this->$name;
return null;
}
public function connect($host,$user,$pass,$db,$charSet='utf8',$force=false)
{
if($this->db && ($this->db instanceof mysqli) && !$force)
{
return ;
}
$this->db=new mysqli($host,$user,$pass,$db);
if (mysqli_connect_error()) {
die('Connect Error (' . mysqli_connect_errno() . ') '
. mysqli_connect_error());
}
$this->db->set_charset($charSet);
}
//$dbname string
//返回值 如果成功则返回 TRUE,失败则返回 FALSE。
function select_db ($dbname )
{
return $this->db->select_db($dbname);
}
//$query mysqli_result
//$resulttype int MYSQLI_ASSOC, MYSQLI_NUM, or MYSQLI_BOTH. Defaults to MYSQLI_BOTH.
//返回值 Returns an array of strings that corresponds to the fetched row or NULL if there are no more rows in resultset.
function fetch_array(/*mysqli_result*/ $query, $resulttype = MYSQLI_ASSOC)
{
//var_dump(!null);
if(!$query || !($query instanceof mysqli_result))
return NULL;
return $query->fetch_array($resulttype);//
}
function data_seek($result,$offset)
{
return $result->data_seek($offset);
}
function fetch_assoc($query)
{
return $query->fetch_assoc();// 关联数组
}
function fetch_row($query)
{
return $query->fetch_row();// 索引数组,数字0,1。eg。。。
}
function fetch_fields($query)
{
return $query->fetch_fields();
}
//$query string
//$resultmode int
//返回值 如果成功则返回 TRUE,失败则返回 FALSE。 For SELECT, SHOW, DESCRIBE or EXPLAIN mysqli_query() will return a result object.
public function query($sql ,$resultmode=MYSQLI_STORE_RESULT )
{
if(MYSQL_OPEN_LOGS) {
$sqlstarttime = $sqlendttime = 0;
$mtime = explode(' ', microtime());
$sqlstarttime = $mtime[1]+ $mtime[0] ;
}
//真正查询
$query=$this->db->query($sql,$resultmode);
if(MYSQL_OPEN_LOGS) {
// sleep(1);
$mtime = explode(' ', microtime());
$sqlendttime = $mtime[1] + $mtime[0] ;
$sqlQueryTime = number_format($sqlendttime - $sqlstarttime,6);
//dblogs($sql, $sqlQueryTime,1);
$explain = array();
$info = $this->db->info;
if($query && preg_match("/^(select )/i", $sql)) {
$explain = $this->fetch_array($this->db->query('EXPLAIN '.$sql), MYSQLI_ASSOC );
}
$GLOBALS['mysql_debug_query'][] = array('sql'=>$sql, 'time'=>$sqlQueryTime, 'info'=>$info, 'explain'=>$explain);
}
if(!$query)
{
$this->halt('MySQL Query Error', $sql);
}
return $query;
}
//返回值 mysqli_stmt对象
function prepare($sql)
{
return $this->db->prepare($sql);
}
function affected_rows() {
return $this->db->affected_rows;
}
function error()
{
return $this->db->error;
}
function errno()
{
return $this->db->errno;
}
//result 没有
function num_rows($query)
{
return $query->num_rows;
}
//返回值 int The number of fields from a result set.
//也可以用另外一种方式 mysqliHelp->db->field_count返回。
function num_fields($query)
{
return $query->field_count;
}
function free_result($query)
{
//all methods are equivalent;
$query->free();
//$query->free_result();
//$query->close();
}
function insert_id()
{
if(($id = $this->db->insert_id)>= 0)
{
return $id;
}else
{
$idArr=$this->fetch_array($this->query("SELECT last_insert_id() as id"));
return intval($idArr[0]);
}
//return ($idArr=$this->fetch_array($this->query("SELECT last_insert_id() as id")))[0]
//return ($id = $this->db-insert_id)>= 0 ? $id : 0 ;
}
function close() {
return $this->db->close();
}
function halt($message,$sql)
{
$dberror = $this->error();
$dberrno = $this->errno();
$help_link = "http://faq.comsenz.com/?type=mysql&dberrno=".rawurlencode($dberrno)."&dberror=".rawurlencode($dberror);
echo "<div position:absolute;font-size:11px;font-family:verdana,arial;background:#EBEBEB;padding:0.5em;\">
<b>MySQL Error</b><br>
<b>Message</b>: $message<br>
<b>SQL</b>: $sql<br>
<b>Error</b>: $dberror<br>
<b>Errno.</b>: $dberrno<br>
<a href=/index.html"$help_link\" target=\"_blank\">Click here to seek help.</a>
</div>";
exit();
}
function __destruct()
{
$this->db=null;
}
/* MySQLi类
面向对象接口 面向过程接口 别名 描述
属性
$mysqli->affected_rows mysqli_affected_rows() N/A 获取前一个Mysql操作的受影响行数
$mysqli->client_info mysqli_get_client_info() N/A 返回字符串类型的Mysql客户端版本信息
$mysqli->client_version mysqli_get_client_version() N/A 返回整型的Mysql客户端版本信息
$mysqli->connect_errno mysqli_connect_errno() N/A 返回最后一次连接调用的错误代码
$mysqli->connect_error mysqli_connect_error() N/A 返回一个字符串描述的最后一次连接调用的错误代码
$mysqli->errno mysqli_errno() N/A 返回最近的函数调用产生的错误代码
$mysqli->error mysqli_error() N/A 返回字符串描述的最近一次函数调用产生的错误代码
$mysqli->field_count mysqli_field_count() N/A 返回最近一次查询获取到的列的数目
$mysqli->host_info mysqli_get_host_info() N/A 返回一个能够代表使用的连接类型的字符串
$mysqli->protocol_version mysqli_get_proto_info() N/A 返回使用的Mysql协议的版本信息
$mysqli->server_info mysqli_get_server_info() N/A 返回Mysql服务端版本的信息
$mysqli->server_version mysqli_get_server_version() N/A 返回整型的Mysql服务端版本信息
$mysqli->info mysqli_info() N/A 最近一次执行的查询的检索信息
$mysqli->insert_id mysqli_insert_id() N/A 返回最后一次查询自动生成并使用的id
$mysqli->sqlstate mysqli_sqlstate() N/A 返回前一个Mysql操作的SQLSTATE错误
$mysqli->warning_count mysqli_warning_count() N/A 返回给定链接最后一次查询的警告数量
方法
mysqli->autocommit() mysqli_autocommit() N/A 打开或关闭数据库的自动提交功能
mysqli->change_user() mysqli_change_user() N/A 更改指定数据库连接的用户
mysqli->character_set_name(), mysqli->client_encoding mysqli_character_set_name() mysqli_client_encoding() 返回数据库连接的默认字符集
mysqli->close() mysqli_close() N/A 关闭先前打开的数据库连接
mysqli->commit() mysqli_commit() N/A 提交当前事务
mysqli::__construct() mysqli_connect() N/A 打开一个到Mysql服务端的新的连接[注意:静态方法]
mysqli->debug() mysqli_debug() N/A 执行调试操作
mysqli->dump_debug_info() mysqli_dump_debug_info() N/A 将调试信息转储到日志中
mysqli->get_charset() mysqli_get_charset() N/A 返回对象的字符集
mysqli->get_connection_stats() mysqli_get_connection_stats() N/A 返回客户端连接的统计信息。 仅可用于 mysqlnd。
mysqli->get_client_info() mysqli_get_client_info() N/A 返回字符串描述的Mysql客户端版本
mysqli->get_client_stats() mysqli_get_client_stats() N/A 返回每个客户端进程的统计信息。 仅可用于 mysqlnd。
mysqli->get_cache_stats() mysqli_get_cache_stats() N/A 返回客户端的zval缓存统计信息。 仅可用于 mysqlnd。
mysqli->get_server_info() mysqli_get_server_info() N/A 没有文档
mysqli->get_warnings() mysqli_get_warnings() N/A 没有文档
mysqli::init() mysqli_init() N/A 初始化mysqli并且返回一个由mysqli_real_connect使用的资源类型。[不是在对象上,是它返回的$mysqli对象]
mysqli->kill() mysqli_kill() N/A 请求服务器杀死一个Mysql线程
mysqli->more_results() mysqli_more_results() N/A 检查一个多语句查询是否还有其他查询结果集
mysqli->multi_query() mysqli_multi_query() N/A 在数据库上执行一个多语句查询
mysqli->next_result() mysqli_next_result() N/A 从multi_query中准备下一个结果集
mysqli->options() mysqli_options() mysqli_set_opt() 设置选项
mysqli->ping() mysqli_ping() N/A ping一个服务器连接,或者如果那个连接断了尝试重连
mysqli->prepare() mysqli_prepare() N/A 准备一个用于执行的SQL语句
mysqli->query() mysqli_query() N/A 在数据库上执行一个查询
mysqli->real_connect() mysqli_real_connect() N/A 打开一个到Mysql服务端的连接
mysqli->real_escape_string(), mysqli->escape_string() mysqli_real_escape_string() mysqli_escape_string() 转义字符串中用于SQL语句中的特殊字符,这个转换会考虑连接的当前字符集。
mysqli->real_query() mysqli_real_query() N/A 执行一个SQL查询
mysqli->rollback() mysqli_rollback() N/A 回滚当前事务
mysqli->select_db() mysqli_select_db() N/A 为数据库查询选择默认数据库
mysqli->set_charset() mysqli_set_charset() N/A 设置默认的客户端字符集
mysqli->set_local_infile_default() mysqli_set_local_infile_default() N/A 清除用户为load data local infile命令定义的处理程序
mysqli->set_local_infile_handler() mysqli_set_local_infile_handler() N/A 设置LOAD DATA LOCAL INFILE命令执行的回调函数
mysqli->ssl_set() mysqli_ssl_set() N/A 使用SSL建立安装连接
mysqli->stat() mysqli_stat() N/A 获取当前系统状态
mysqli->stmt_init() mysqli_stmt_init() N/A 初始化一个语句并且返回一个mysqli_stmt_prepare使用的对象
mysqli->store_result() mysqli_store_result() N/A 传输最后一个查询的结果集
mysqli->thread_id() mysqli_thread_id() N/A 返回当前连接的线程ID
mysqli->thread_safe() mysqli_thread_safe() N/A 返回是否设定了线程安全
mysqli->use_result() mysqli_use_result() N/A 初始化一个结果集的取回
*/
/*
MySQL_STMT
面向对象接口 过程化接口 别名(不要使用) 描述
属性
$mysqli_stmt->affected_rows mysqli_stmt_affected_rows() N/A 返回最后一条倍执行的语句改变,删除或插入的总行数
$mysqli_stmt->errno mysqli_stmt_errno() N/A 返回最近一次语句调用的错误代码
$mysqli_stmt->error mysqli_stmt_error() N/A 返回最后一条语句错误的字符串描述
$mysqli_stmt->field_count mysqli_stmt_field_count() N/A 返回给定语句得到的字段数量
$mysqli_stmt->insert_id mysqli_stmt_insert_id() N/A 获取前一个INSERT操作生成的ID
$mysqli_stmt->num_rows mysqli_stmt_num_rows() N/A 返回语句结果集中的行数
$mysqli_stmt->param_count mysqli_stmt_param_count() mysqli_param_count() 返回给定语句中参数数量
$mysqli_stmt->sqlstate mysqli_stmt_sqlstate() N/A 返回前一个语句操作的SQLSTATE错误代码
方法
mysqli_stmt->attr_get() mysqli_stmt_attr_get() N/A 用于获取语句属性的当前值
mysqli_stmt->attr_set() mysqli_stmt_attr_set() N/A 用于修改prepared语句的行为
mysqli_stmt->bind_param() mysqli_stmt_bind_param() mysqli_bind_param() 将一个变量作为参数绑定到prepared语句上
mysqli_stmt->bind_result() mysqli_stmt_bind_result() mysqli_bind_result() 将一个变量绑定到一个prepared语句上用于结果存储
mysqli_stmt->close() mysqli_stmt_close() N/A 关闭一个prepared语句
mysqli_stmt->data_seek() mysqli_stmt_data_seek() N/A 查看语句结果集中的任意行
mysqli_stmt->execute() mysqli_stmt_execute() mysqli_execute() 执行一个prepared查询
mysqli_stmt->fetch() mysqli_stmt_fetch() mysqli_fetch() 从一个prepared语句中抓取结果到限定变量中
mysqli_stmt->free_result() mysqli_stmt_free_result() N/A 释放给定语句处理存储的结果集所占内存
$mysqli_stmt->get_result() mysqli_stmt_get_result N/A 没有文档 仅可用于 mysqlnd。
mysqli_stmt->get_warnings() mysqli_stmt_get_warnings() N/A 没有文档
$mysqli_stmt->more_results() mysqli_stmt_more_results() N/A 没有文档 仅可用于 mysqlnd。
$mysqli_stmt->next_result() mysqli_stmt_next_result() N/A 没有文档 仅可用于 mysqlnd。
mysqli_stmt->num_rows() mysqli_stmt_num_rows() N/A 查阅属性$mysqli_stmt->num_rows
mysqli_stmt->prepare() mysqli_stmt_prepare() N/A 准备一个SQL语句用于执行
mysqli_stmt->reset() mysqli_stmt_reset() N/A 重置一个prepared语句
mysqli_stmt->result_metadata() mysqli_stmt_result_metadata() mysqli_get_metadata() 从一个prepared语句返回结果集元数据
mysqli_stmt->send_long_data() mysqli_stmt_send_long_data() mysqli_send_long_data() 发送数据块
mysqli_stmt->store_result() mysqli_stmt_store_result() N/A 从一个prepared语句中传输一个结果集
*/
/*
MySQLi_RESULT
面向对象接口 过程化接口 别名(不要使用) 描述
属性
$mysqli_result->current_field mysqli_field_tell() N/A 获取当前字段在结果集指针中的开始位置
$mysqli_result->field_count mysqli_num_fields() N/A 获取结果中字段数量
$mysqli_result->lengths mysqli_fetch_lengths() N/A 返回结果集中当前行的每列的值得长度,返回数组
$mysqli_result->num_rows mysqli_num_rows() N/A 获取结果中行的数量
方法
mysqli_result->data_seek() mysqli_data_seek() N/A 将结果中的结果指针调整到任意行
mysqli_result->fetch_all() mysqli_fetch_all() N/A 抓取所有的结果行并且以关联数据,数值索引数组,或者两者皆有的方式返回结果集。仅可用于 mysqlnd。
mysqli_result->fetch_array() mysqli_fetch_array() N/A 以一个关联数组,数值索引数组,或者两者皆有的方式抓取一行结果
mysqli_result->fetch_assoc() mysqli_fetch_assoc() N/A 以一个关联数组方式抓取一行结果
mysqli_result->fetch_field_direct() mysqli_fetch_field_direct() N/A 抓取一个单字段的元数据
mysqli_result->fetch_field() mysqli_fetch_field() N/A 返回结果集中的下一个字段
mysqli_result->fetch_fields() mysqli_fetch_fields() N/A 返回一个代表结果集字段的对象数组
mysqli_result->fetch_object() mysqli_fetch_object() N/A 以一个对象的方式返回一个结果集中的当前行
mysqli_result->fetch_row() mysqli_fetch_row() N/A 以一个枚举数组方式返回一行结果
mysqli_result->field_seek() mysqli_field_seek() N/A 设置结果指针到特定的字段开始位置
mysqli_result->free(), mysqli_result->close, mysqli_result->free_result mysqli_free_result() N/A 释放与一个结果集相关的内存
*/
/*注意 MYSQLI_STORE_RESULT和MYSQLI_USE_RESULT的区别
其实这两个参数的区别还是很大的。
(1)区别在于从服务器上检索结果集的行。
(2)MYSQLI_USE_RESULT 启动查询,但实际上并未获取任何行
(3)MYSQLI_STORE_RESULT 立即检索所有的行
(4)MYSQLI_STORE_RESULT 从服务器上检索结果集时,就提取了行,并为之分配内存,存储到客户机中,随后调用
mysqli_fetch_array()就再也不会返回错误,因为它仅仅是把行脱离了已经保留结果集的数据结 构,mysqli_fetch_array()返回 NULL始终表示已经到达结果集的末端。
(5)MYSQLI_USE_RESULT 本身不检索任何行,而只是启动一个逐行的检索,就是说必须对每行调 用
mysqli_fetch_array()来自己完成。既然如此,虽然正常情况下,mysqli_fetch_array()返回NULL仍然表示此 时已到达结果集的末端,但也可能表示在与服务器通信时发生错误。
如果是MYSQLI_USE_RESULT,query以后得到mysqli_result对象后,执行data_seek会出错,因为
mysqli_result::data_seek() [mysqli-result.data-seek]: Function cannot be used with MYSQL_USE_RESULT
与MYSQLI_USE_RESULT相比,MYSQLI_STORE_RESULT 有着较高的内存和处理需求,因为是在客户机上维护整个结果集,所以内存分配和创建数据结构的耗费是非常巨大的,如果想一次检索多个行,可用 MYSQLI_USE_RESULT。
MYSQLI_USE_RESULT有着较低的内存需求,因为只需给每次处理的单行分配足够的空间。这样速度就较快,因为不必为结果集建立复杂的数据结构。
另一方面,MYSQLI_USE_RESULT把较大的负载加到了服务器上,它必须保留结果集中的行,直到客户机看起来适合检索所有的行。
*/
}
$dbHelper=new mysqliHelp;
$dbHelper->connect('localhost', 'root', '', 'tt');
//$dbHelper->db->select_db("tt");
//$dbHelper->db->set_charset("utf8");
//这里如果是MYSQLI_USE_RESULT,下面的$dbHelper->data_seek($query,10);就会出错
$query=$dbHelper->query("select id,cateid,title from product limit 22",MYSQLI_STORE_RESULT );
//$query=$dbHelper->query("update product set createtime=UNIX_TIMESTAMP() limit 22");
//$query=$dbHelper->query("insert into `product`(`cateid`,`title`,`text`,`createtime`) values (2,'test','content',1284822691)");
//$query=$dbHelper->query("delete from `product` where id=1");
//$query=$dbHelper->query("replace into product(id,cateid,title,text,createtime) values(1,2,'this is demo','test',UNIX_TIMESTAMP())");
echo $query->num_rows."总数";
//var_dump($query);
//$row=$dbHelper->fetch_array($query);
//var_dump($row);
//finfo = $dbHelper->fetch_fields($query);
//var_dump($finfo);
// foreach ($finfo as $val) {
// printf("Name: %s\n", $val->name);
// printf("Table: %s\n", $val->table);
// printf("max. Len: %d\n", $val->max_length);
// printf("Flags: %d\n", $val->flags);
// printf("Type: %d\n\n", $val->type);
// }
//如果是查询操作affected_rows行数为1,num_rows为查询结果行数,num_fields为字段数目
//如果是更新或者删除操作affected_rows为受影响的行数,num_rows为null,num_fields为null
//
$dbHelper->data_seek($query,10);
$row=$dbHelper->fetch_row($query);
var_dump($row);
echo "影响行数:", "<br/>";
var_dump($dbHelper->affected_rows());
//var_dump($dbHelper->db->affected_rows );
echo "查询行数","<br/>";
var_dump($dbHelper->num_rows($query));
echo "列数:","<br/>";
var_dump($dbHelper->num_fields($query));
//第1种
$sql="select id,cateid,title from product where cateid=? and title like ? and createtime<".time();
$stmt=$dbHelper->prepare($sql);
var_dump($stmt);
$stmt->bind_param('is',$cateid,$title);
$title="%%";
$cateid=10;
$stmt->execute();
$stmt->bind_result($col1, $col2,$col3);
/* fetch values */
while ($stmt->fetch()) {
printf("%s %s"."<br/>", $col1, $col3);
}
echo "<br/>";
$title="%%";
$cateid=4;
$stmt->execute();
$stmt->bind_result($col1, $col2,$col3);
/* fetch values */
while ($stmt->fetch()) {
printf("%s %s %s"."<br/>", $col1, $col2,$col3);
}
$stmt->close();
//第2种
$stmt=$dbHelper->db->stmt_init();
$stmt->prepare($sql);
$stmt->bind_param('is',$cateid,$title);
$title="%%";
$cateid=10;
$stmt->execute();
$stmt->bind_result($col1, $col2,$col3);
/* fetch values */
while ($stmt->fetch()) {
//printf("%s %s"."<br/>", $col1, $col3);
}
echo "<br/>开始multi_query:<br/>";
//multi_query实例
//multi_query()方法的返回值,以及 //mysqli的属性errno、error、info等只与第一条SQL命令有关,无法判断第二条及以后的命令是否在执行时发生了错误。所以在执行 //multi_query()方法的返回值是TRUE时,并不意味着后续命令在执行时没有出错。
$sql="select id,cateid,title from product where cateid=4;";
$sql.="select id,cateid,title from product where cateid=10";
$query=$dbHelper->db->multi_query($sql);
if($query)
{
do {
/* store first result set */
//下面两种方法有什么区别?
// if ($result = $dbHelper->db->store_result()) {
// while ($row = $result->fetch_row()) {
// $data[]=$row;
// }
// $result->free();
// }
if ($result = $dbHelper->db->use_result()) {//返回mysqli_result类型
//$result->data_seek(0);//返回bool
while ($row = $result->fetch_row()) {
$data[]=$row;
}
//$result->close();
}
/* print divider */
if ($dbHelper->db->more_results()) {
printf("-----------------\n");
$data[]="_______________________________";
}
} while ($dbHelper->db->next_result());
}
var_dump($data);
//exit;
//执行事务 实例
//确保操作的表时innodb类型的表
//如果是MyISAM,逻辑出错的话, 会执行所有操作,不回滚
$price=1;
$success=true;
$dbHelper->db->autocommit(0);
$result=$dbHelper->query("update product set cateid=cateid-$price where id=1000" );
if(!$result || $dbHelper->affected_rows()!=1)
{
$success=false;
}
$result=$dbHelper->query("update product set cateid=cateid+$price where id=2");
if(!$result || $dbHelper->affected_rows()!=1)
{
$success=false;
}
if($success)
{
$dbHelper->db->commit();
echo "成功";
}else
{
$dbHelper->db->rollback();
echo "失败";
}
$dbHelper->db->autocommit(1);
//var_dump( $dbHelper->insert_id());
var_dump($mysql_debug_query); //打印sql查询信息
//
?>