[英]How do i optimize my php functions and mysql request
我刚刚编写了此php跟踪程序代码,该代码将包含在主题中,以具有一些简单的统计信息。 现在,由于它将处理大量请求,因此它必须稳定且快速。 我的php级别不是很好,所以我正在寻找帮助/最佳实践来优化这个坏男孩。
我编写了一个简单的.htaccess文件,该文件将所有请求重定向到index.php,因此我可以使用php处理请求uri: $_SERVER['REQUEST_URI'], /this-is-the-theme-slug /user-name
<?php
/** MySQL Database Settings */
require dirname(__FILE__) . '/inc/database.php';
/** Klogger Log Framework*/
require dirname(__FILE__) . '/lib/KLogger.php';
$log = KLogger::instance(dirname(__FILE__).'/log/', KLogger::DEBUG);
/** Process Request String **/
$request = $_SERVER['REQUEST_URI'];
$ipaddr = $_SERVER['REMOTE_ADDR'];
$uri = explode('/',$request);
$slug = $uri[1];
$user = $uri[2];
/** Global Variables **/
$theme_id = NULL;
$account_id = NULL;
function process_request(){
global $log, $slug, $user;
if(!empty($slug) && !empty($user)){
$the_slug = validate_slug($slug);
$the_user = account_exists($user);
if($the_slug){ // if the slug is valid
if($the_user){ // and the user exists
// update entry
update_entry($user);
}else{
// create new entry
create_entry($user);
}
}
return true;
}else{
$log->logError('process_request:: Bad request');
return false;
}
}
function validate_slug($slug){
global $log, $theme_id;
$con = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
if(!$con){
$log->logError('validate_slug:: Database connection failed');
return false;
}else{
$select = mysql_select_db(DB_NAME, $con);
$query = sprintf("SELECT id FROM ".DB_PREFIX."themes WHERE slug='%s'", mysql_real_escape_string($slug));
$result = mysql_query($query);
if(mysql_num_rows($result)==0){
$log->logNotice('validate_slug:: Slug not found');
return false;
}else{
$theme_id = mysql_result($result,0);
return true;
}
mysql_close($con);
}
}
function account_exists($user){
global $log, $account_id;
$con = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
if(!$con){
$log->logError('account_exists:: Database connection failed');
return false;
}else{
$select = mysql_select_db(DB_NAME, $con);
$query = sprintf("SELECT id FROM ".DB_PREFIX."stats WHERE account='%s'", mysql_real_escape_string($user));
$result = mysql_query($query);
if(mysql_num_rows($result)==0){
$log->logNotice('account_exists:: Account not found');
return false;
}else{
$account_id = mysql_result($result,0);
return true;
}
mysql_close($con);
}
}
function create_entry($user){
global $log, $ipaddr, $theme_id;
$con = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
if(!$con){
$log->logError('create_entry:: Database connection failed');
return false;
}else{
$select = mysql_select_db(DB_NAME, $con);
$query = sprintf("INSERT INTO ".DB_PREFIX."stats (id,active,account,date,ip,hits,theme) VALUES ('','1','%s',NOW(),'".$ipaddr."','1','".$theme_id."')", mysql_real_escape_string($user));
$result = mysql_query($query);
$log->logNotice('create_entry:: Account created with id '.mysql_insert_id() );
return true;
}
mysql_close($con);
}
function update_entry($user){
global $log, $ipaddr, $account_id;
$con = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
if (!$con) {
$log->logError('update_entry:: Database connection failed');
return false;
} else {
$select = mysql_select_db(DB_NAME, $con);
$query = sprintf("UPDATE ".DB_PREFIX."stats SET date=NOW(),ip='".$ipaddr."',hits=hits+1 WHERE id='".$account_id."'");
$result = mysql_query($query);
$log->logNotice('update_entry:: Entry with id '.$account_id.' is updated.' );
return true;
}
mysql_close($con);
}
process_request();
编辑我已经为跟踪器成功创建了一个工作类,请参见下面的代码。 如果您的速度有所提高,请告诉我! 我尝试使用mysqlli和pdo进行连接,但是它不起作用,显然我的主机不支持它?
<?php
require_once(__DIR__ . '/inc/database.php');
require_once(__DIR__ . '/lib/KLogger.php');
Class ThemeStatsTracker
{
public $log;
private $theme_name;
private $theme_user;
private $theme_name_db_id;
private $theme_user_db_id;
public function __construct()
{
// Setup Log
$this->log = KLogger::instance(dirname(__FILE__).'/log/', KLogger::DEBUG);
// Process URI variables
$uri = explode('/',$_SERVER['REQUEST_URI']);
$this->theme_name = (!empty($uri[1])) ? $uri[1] : NULL;
$this->theme_user = (!empty($uri[2])) ? $uri[2] : NULL;
// Handle the Request
$this->database_connect();
if($this->validate_theme()){
if($this->user_entry_exists()){
$this->user_entry_update();
}else{
$this->user_entry_create();
}
}
// Always serve an image as response
$this->serve_image();
}
private function validate_theme()
{
$query = sprintf("SELECT id FROM ".DB_PREFIX."themes WHERE slug='%s' LIMIT 1", mysql_real_escape_string($this->theme_name));
$result = mysql_query($query);
if (!$result){
$this->log->logError(__FUNCTION__ . ' FAIL: ' . $query . ' BECAUSE: ' . mysql_error());
return FALSE;
}
if(mysql_num_rows($result)==0){
$this->log->logError(__FUNCTION__ . ' Theme name ' . $this->theme_name . ' NOT found');
return FALSE;
}else{
$this->log->logInfo(__FUNCTION__ . ' Theme name ' . $this->theme_name . ' found');
$this->theme_name_db_id = mysql_result($result,0);
return TRUE;
}
}
private function user_entry_exists()
{
$query = sprintf("SELECT id FROM ".DB_PREFIX."stats WHERE account='%s' LIMIT 1", mysql_real_escape_string($this->theme_user));
$result = mysql_query($query);
if (!$result){
$this->log->logError(__FUNCTION__ . ' FAIL: ' . $query . ' BECAUSE: ' . mysql_error());
return FALSE;
}
if(mysql_num_rows($result)==0){
$this->log->logInfo(__FUNCTION__ . ' New user ' . $this->theme_user);
return FALSE;
}else{
$this->log->logInfo(__FUNCTION__ . ' Existing user ' . $this->theme_user);
$this->theme_user_db_id = mysql_result($result,0);
return TRUE;
}
}
private function user_entry_create()
{
$query = sprintf("INSERT INTO ".DB_PREFIX."stats (id,active,account,date,ip,hits,theme) VALUES ('','1','%s',NOW(),'".$_SERVER['REMOTE_ADDR']."','1','".$this->theme_name_db_id."')", mysql_real_escape_string($this->theme_user));
$result = mysql_query($query);
if (!$result){
$this->log->logError(__FUNCTION__ . ' FAIL: ' . $query . ' BECAUSE: ' . mysql_error());
return FALSE;
}
$this->log->logNotice(__FUNCTION__ . ' New user created with id ' . mysql_insert_id());
return TRUE;
}
private function user_entry_update()
{
$query = sprintf("UPDATE ".DB_PREFIX."stats SET date=NOW(),ip='".$_SERVER['REMOTE_ADDR']."',hits=hits+1 WHERE id='".$this->theme_user_db_id."' LIMIT 1");
$result = mysql_query($query);
if (!$result){
$this->log->logError(__FUNCTION__ . ' FAIL: ' . $query . ' BECAUSE: ' . mysql_error());
return FALSE;
}
$this->log->logNotice(__FUNCTION__ . ' User with id ' . $this->theme_user_db_id . 'updated');
return TRUE;
}
private function serve_image()
{
header("Content-type: image/gif");
header("Content-length: 43");
$fp = fopen("php://output","wb");
fwrite($fp,"GIF89a\x01\x00\x01\x00\x80\x00\x00\xFF\xFF",15);
fwrite($fp,"\xFF\x00\x00\x00\x21\xF9\x04\x01\x00\x00\x00\x00",12);
fwrite($fp,"\x2C\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02",12);
fwrite($fp,"\x44\x01\x00\x3B",4);
fclose($fp);
}
private function database_connect()
{
$con = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
if(!$con){
$this->log->logError(__FUNCTION__ . ' FAIL: ' . $query . ' BECAUSE: ' . mysql_error());
return FALSE;
}
$select = mysql_select_db(DB_NAME, $con);
if (!$select){
$this->log->logError(__FUNCTION__ . ' FAIL: ' . $query . ' BECAUSE: ' . mysql_error());
return FALSE;
}
}
}
$stats = new ThemeStatsTracker();
每当存在潜在的性能问题时,您都可以打赌,它通常位于I / O子系统和现代Web应用程序中,这通常意味着数据库,因此可以在其中查找和修复性能问题。 这是我的简要经验法则。
这些是可以应用于查询语句的一般原则。
按照上面的代码中的具体说明,使服务器连接,并在脚本开始处选择一次数据库。 连接和选择在范围上实际上是全局的。 删除关闭连接语句。 PHP垃圾收集器将为您完成此任务。
您可能需要阅读query()函数。 大多数数据库函数返回值,通常是失败时返回资源或FALSE。 您的脚本应测试这些值并处理行为。 MySQL不是黑匣子; 它可能会由于您无法控制的原因而失败。 发生这种情况时,您要记录错误并发出警报。
您可能考虑使用面向对象的表示法重写此内容,对$ slug和$ log这样的东西使用受保护的类属性。 这将帮助您避免使用全局语句,因为这会破坏封装,因此这是避免混淆的可靠途径。
HTH,〜雷
为了进行比较,这就是我可能使用OOP表示法编写跟踪器的方式。 我从未对此进行过测试,但似乎非常正确。 另外,PHP具有内置功能来记录错误和通知。 http://php.net/manual/zh/function.error-log.php
<?php // RAY_temp_ckdt.php
error_reporting(E_ALL);
/** MySQL Database CONSTANT DEFINITIONS */
require_once( __DIR__ . '/inc/database.php');
/** Klogger Log Framework*/
require_once( __DIR__ . '/lib/KLogger.php');
$log = KLogger::instance(dirname(__FILE__).'/log/', KLogger::DEBUG);
Class Tracker
{
protected $return, $slug, $user, $theme_id, $account_id;
public function __construct($log)
{
$this->return = TRUE;
$this->log = $log;
$con = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
if(!$con){
$this->log->logError('DB FAIL: ' . mysql_error());
}
$select = mysql_select_db(DB_NAME, $con);
if (!$select){
$this->log->logError('DB FAIL: ' . mysql_error());
return FALSE;
}
$uri = explode(DIRECTORY_SEPARATOR, $_SERVER['REQUEST_URI']);
$this->slug = (!empty($uri[1])) ? $uri[1] : NULL;
$this->user = (!empty($uri[2])) ? $uri[2] : NULL;
if(empty($this->slug) || !empty($this->user)){
$this->log->logError(__FUNCTION__ . ": Bad request");
return FALSE;
}
$the_slug = validate_slug($this->slug);
$the_user = account_exists($this->user);
if($the_slug){
if($the_user){
update_entry();
}else{
create_entry();
}
}
return $this->return;
}
protected function validate_slug(){
$query = sprintf("SELECT id FROM ".DB_PREFIX."themes WHERE slug='%s' LIMIT 1", mysql_real_escape_string($this->slug));
$result = mysql_query($query);
if (!$result){
$this->log->logError(__FUNCTION__ . "FAIL: $query BECAUSE: " . mysql_error());
$this->return = FALSE;
return FALSE;
}
if(mysql_num_rows($result)==0){
$this->log->logNotice(__FUNCTION__ . ": Slug $this->slug not found");
$this->return = FALSE;
return FALSE;
}else{
$this->theme_id = mysql_result($result,0);
$this->return = TRUE;
return TRUE;
}
}
protected function account_exists(){
$query = sprintf("SELECT id FROM ".DB_PREFIX."stats WHERE account='%s' LIMIT 1", mysql_real_escape_string($this->user));
$result = mysql_query($query);
if (!$result){
$this->log->logError(__FUNCTION__ . "FAIL: $query BECAUSE: " . mysql_error());
$this->return = FALSE;
return FALSE;
}
if(mysql_num_rows($result)==0){
$this->log->logNotice(__FUNCTION__ . ": Account $this->user not found");
$this->return = FALSE;
return FALSE;
}else{
$this->account_id = mysql_result($result,0);
$this->return = TRUE;
return TRUE;
}
}
protected function create_entry(){
$query = sprintf("INSERT INTO ".DB_PREFIX."stats (id,active,account,date,ip,hits,theme) VALUES ('','1','%s',NOW(),'".$_SERVER['REMOTE_ADDR']."','1','".$theme_id."')", mysql_real_escape_string($this->user));
$result = mysql_query($query);
if (!$result){
$this->log->logError(__FUNCTION__ . "FAIL: $query BECAUSE: " . mysql_error());
$this->return = FALSE;
return FALSE;
}
$this->log->logNotice(__FUNCTION__ . ': Account created with id '.mysql_insert_id() );
$this->return = TRUE;
return TRUE;
}
public function update_entry(){
$query = sprintf("UPDATE ".DB_PREFIX."stats SET date=NOW(),ip='".$_SERVER['REMOTE_ADDR']."',hits=hits+1 WHERE id='".$this->account_id."' LIMIT 1");
$result = mysql_query($query);
if (!$result){
$this->log->logError(__FUNCTION__ . "FAIL: $query BECAUSE: " . mysql_error());
$this->return = FALSE;
return FALSE;
}
$this->log->logNotice(__FUNCTION__ . ': Entry with id '.$account_id.' is updated.' );
$this->return = TRUE;
return TRUE;
}
} // END CLASS TRACKER
// TRACK THIS REQUEST
$x = new Tracker($log);
优化俱乐部的规则:
最重要的规则是#1。 如果您不知道自己的代码运行缓慢,请不要尝试加快速度。 然后,对于#2,如果您认为需要加快速度,则必须衡量它的速度是否较慢。 这可能是技术含量低的技术,例如在整个代码中放置print microtime()
调用,这样您就可以看到单个代码块要运行多长时间,或者可以使用XDebug之类的性能分析工具来确切地发现哪些代码行需要多长时间。跑步。
无论您做什么,都不要使用可运行的代码,而只是对其进行重击以试图使其更快。
(而且,与您的问题无关,您应该使用参数化查询来确保安全和简便: http : //bobby-tables.com/php.html包含示例)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.