最近可能会写比较多的监控页面,实际就是一系列的数据库查询,方便开发人员查询,只需要输入特定的订单号,就能够把相关的所有表,需要相关的表内的数据都查询出来。由于之前已经存在一定的模板了,所以做起来很轻松,我想总结一下学习到的一些PHP及SQL知识,都是比较偏基础的,只适合小白看看。
我将参考PHP手册详细解读这些代码,我对代码进行了适当的修改,比如涉及到数据库的一些SQL,一些文件名,变量名等等。
part 1:
define('IN_ECS',true);require('../includes/init.php');require_once('monitor.php');
ecshop系统里的有些.php页是不需要用户通过url直接访问的,它是用来被其它页调用的。例如/includes/init.php,就不需要直接访问,通过url访问你的网址/includes/init.php是无意义的,所以我们在可以直接方问的php里加上define('IN_ECS', true);
它定义这个常量的目的是为了防止被引用文件的非法载入,在系统内全局搜索可以发现,存在下面这样一段代码:
if (!defined('IN_ECS')) { die('Hacking attempt'); }
表示如果页面没有被定义IN_ECS,就停止运行脚本,并显示"Hacking attempt"。
例如:上述代码,先设置IN_ECS的值为true,然后才去加载init.php,这样init.php文件中IN_ECS的值就为true,这时候也可以引入monitor.php,因为此时IN_ECS的值也是为true。
require() :该语句包含并运行指定文件。
require_once() :该语句在脚本执行期间包含并运行指定文件。此行为和require()语句类似,唯一的区别是如果该文件中的代码已经被包含了,就不会再次包含。
在此顺便比较一下include()与require()的区别:它们除了处理失败的方式不同外,别的方面都是一模一样的。include()是产生一个警告,而require()则是导致一个致命错误。如果希望发生错误/丢失页面以后就停止运行页面,需要用require(),因为include()只是产生一个警告并继续运行。
而include_once() 相对于 include() 唯一的区别就是如果该文件中的代码已经被包含了,就不会再次包含。
part 2:
$monitor_header = new MonitorHeader("监控页",array('order_a','order_b'));$smarty -> assign('monitor_header',$monitor_header);
MonitorHeader 是自定义的一个类,当然啦,不是我创建的,通过全局搜索我找到了这个类
class MonitorHeader{ public $title_ = '页面标题'; public $search_condition_list_ = array('检索参数'); public $back_url_ = '表单提交链接'; function __construct($title, $search_condition_list) { $this->title_ = $title; $this->search_condition_list_ = $search_condition_list; $this->back_url_ = end(explode('/',$_SERVER['PHP_SELF'])); }}
暂时不详细展开解读这个类,但是大概能看明白,刚才上面创建的new MonitorHeader是怎么回事,"监控页" 表示的就是页面标题,而后面的array('order_a','order_b')是检索参数,这里的参数有两个,一个order_a,一个order_b,这里没有表单提交链接。
而下面的smarty 采用的是smarty框架,这个框架的优点就是将php与前端的html实现前后端分离,而assign是smarty的函数,那段相当于把$monitor_header的值放到smarty的变量moniotr_header当中,html当中引用这个变量,就会将值显示出来,至于HTML当中如何引用,其实很简单,这里随便举个栗子:
{$monitor_header}
这里的{$monitor_header}相当于PHP文件中的前面那个monitor_header,如果我将代码改写成
$smarty -> assign('m_h',$monitor_header);
则HTML文件则要改成<p>{$m_h}</p>。
part 3:
做完一些准备工作,现在要正式开始对输入的订单号进行判断了,我们可以输入两个关键字段来查询所有相关表,以order_a字段为主,order_b字段为辅,此处的业务内部逻辑就不多说了。
if(empty($_REQUEST['order_a'])&&empty($_REQUEST['order_b'])){ $smarty->assign('msg','请输入order_b或order_a');}else{ if(!empty($_REQUEST['order_a'])){ $order_a=$_REQUEST['order_a']; }else{ $sql="SQL语句通过order_b取出order_a"; $order_a=$db->getOne($sql); } $sql="SQL语句取出结果条数"; $order_count=$db->getOne($sql); if(empty($order_count) || $order_count<=0){ $smarty->assign('smg','请输入正确的order_a或order_b!'); }else{ $smarty->assign('monitor_data',getOrderInfo($order_sn)); }}$smarty->display('common.htm');
上面的代码是一些判断语句,逻辑非常简单,通过empty的作用是判断变量是否已被配置,若变量已存在,非空字符串或者非零,则返回false值,order_a如果没有被$_REQUEST请求到的话,则返回true,会提示"请输入order_b或order_a"。
$sql:我不知道是不是PHP特殊的用法,各种文件里都是这样表示,现在在我看来就是一个专门写SQL语句的变量,为了能更好地识别所以用了sql,其实换成别的名字也没有关系,当然啦,如果我的理解错了我会再回来改正的。
$_REQUEST 是一个超全局变量,意味着它在一个脚本的全部作用域中都可用,$_REQUEST 用来收集前端提交的表单form中input字段的值。其实这个就涉及到了表单提交和后端获取。举个栗子:
HTML表单如下:
XXX.PHP如下:
HTML文件中,写一个form,method是post,还有一种方法是method是get,区别再细数下来久偏题了,在此引用网络上的链接:,侵删。
action 主要是要传递数据的文件,当我们按下按钮以后,会提交表单的数据到xxx.php文件中,这时候后端通过$_REQUEST['fname']来拿到前端name='fname'的input标签的value,也就是我们输入的值。
其实还有多种请求方式,也是超全局变量,比如$_GET,$_POST。当表单提交方式是get,则需要用$_GET,但是不论是get还是post,都可以用$_REQUEST。
接下来分析一下刚才那段大代码中的这句
$order_a=$db->getOne($sql);
->是访问类成员的操作,代码的意思是访问db类的getOne()方法。
ECShop的数据操作类文件是includes/cls_mysql.php,类名是cls_mysql,该类是$db的实例化。关于面向对象的东西不太熟悉,还需要再学习学习。下面是一个小的归纳,别的地方搜刮来的。。
getAll($sql)和getAllCached($sql, $cached = 'FILEFIRST'):获取所有记录。
getRow($sql, $limited = false)和getRowCached($sql, $cached = 'FILEFIRST'):获取单行记录。
getCol($sqlse)和getColCached($sql, $cached = 'FILEFIRST'):获取某栏位的所有值。
getOne($sql, $limited = false)和getOneCached($sql, $cached = 'FILEFIRST'):获取单个数值。
query($sql):执行数据库查询。
autoExecute($table, $field_values, $mode = 'INSERT', $where = ''):数据库表操作。
所以显而易见,getOne()就是获取单个值,此处是获取order_a的值。
getOrderInfo是一个类,该类主要写一些SQL语句,part 4 会讲到。
最后一条,smarty的用法,就是指到common.htm中去display。
part 4:
上面的该判断的判断好了,接下来要写一系列的SQL了,以下面一段代码为例,其余的都是一个套路。
function getJdOrderInfo($order_sn){ $sql = "SELECT * FROM xxx WHERE order_a='{$order_a}'"; $result = FromSQL( '信息表一', $sql, 'order_id'); $servicefg[] = $result['monitor_info']; $sql = "SELECT * FROM xxx WHERE order_a='{$order_a}'"; $result = FromSQL( '信息表二', $sql, 'order_id'); $servicefg[] = $result['monitor_info']; //套路三 //套路四 } return $servicefg;
这里面涉及到许多封装好的内容,首先
第一句给$sql赋值,里面写的就是SQL语句啦~ 注意到后面有一个'{$order_a}',因为该查询字段是字符串类型的,所以要加单引号,{$order_a}是个变量,这个取决于用户输入的order_a的值。
FromSQL是早已被别人写好的 ,里面还带了三个参数,分别表示:表名,SQL语句,查询表的主键,我查到的代码如下:
function FromSQL($table_name, $sql, $primary_key_name, $ref_name_array=array()){ global $db; $extend_ref_name_array = array(); if(!in_array($primary_key_name, $ref_name_array)){ $extend_ref_name_array = array_merge(array($primary_key_name), $ref_name_array); }else{ $extend_ref_name_array = $ref_name_array; } $ref_list = $data_list=array(); $result1 = $db->getAllRefBy($sql, $extend_ref_name_array, $ref_list, $data_list); $table_info = array('table_name'=>$table_name, 'attr_list' =>array(), 'item_list' => array()); $ref_str_list = array(); if(empty($data_list)){ $table_info['attr_list'][] = '无记录'; }else{ foreach ($ref_name_array as $ref_name) { $ref_data_list = $ref_list[$ref_name]; $ref_str_list[$ref_name] = "'". implode($ref_data_list, "','") . "'"; } $data_list = $data_list[$primary_key_name]; $sample = reset($data_list); $attr_list = array(); foreach ($sample[0] as $key => $value) { $attr_list[] = $key; } foreach ($data_list as $key => &$value) { $value = $value[0]; } $table_info['attr_list'] = $attr_list; $table_info['item_list'] = $data_list; } $result = array('monitor_info' => $table_info, 'query_info' => $ref_str_list); return $result;}
太累了~ 我歇会儿~ 这段代码就不分析了,(其实是我没怎么看懂啦~ T^T 逃~),后续再补上吧。。
后面的代码就很简单了,将$result里的monitor_info对应的值放进servicefg数组里。最后再return数组里所有的值,毕竟我们肯定会有很多SQL很多结果,因为要查询到的表很多啊。。
完~ <( ̄▽ ̄)>