目前项目中选用的开发框架是Laravel4,经过几天的阅读源码以及看社区教程,发现是比较先进和强大的框架.
只是对新手入门这块做的很不给力,虽然官方文档在中文化上比较完整,但是相应的文档都是浅尝辄止,项目中用到的东西讲到的都比较少....
为了方便开发测试,所以把firephp予以集成,具体读源码找文档的时间就不说了,大致如下,在 app/start/global.php 文件中加入行:
Log::getMonolog()->pushHandler(new FirePHPHandler(Logger::DEBUG));
然后在代码中使用Log类就能输出结果...
另外对其db查询器使用不是很赶趟,项目组中的妹子也不会用,所以我把AertDb单独领出来做成了插件形式...
<?php /** * laravel Db 简化类 * * @author xuxiaohan */ class Aert_DbRepo { private static $_ds_instances = array(); /** * 为特定存储域选择匹配的存储服务实例 * * @param string $domain * * @return Aert_Db_Query */ static function queryNode($domain='') { $name = empty($domain) ? 'default' : trim($domain); if (!isset(self::$_ds_instances[$name])) { $dbo = empty($domain) ? DB::connection() : DB::connection($domain); self::$_ds_instances[$name] = new Aert_Db_Query($dbo); } return self::$_ds_instances[$name]; } /** * 返回数据库可以接受的日期格式 * * @param int $timestamp * @return string */ static function dbTimeStamp($timestamp) { return date('Y-m-d H:i:s', $timestamp); } /** * 打印输出结果 * * @param mixed $vars * @param string $label * @param bool $return * * @return String */ static function dump($vars, $label = '', $return = false) { $content = "<pre>\n"; if ($label != '') { $content .= "<strong>{$label} :</strong>\n"; } $content .= htmlspecialchars(print_r($vars, true),ENT_COMPAT | ENT_IGNORE); $content .= "\n</pre>\n"; if ($return) { return $content; } echo $content; } } /** * 查询接口 */ class Aert_Db_Query { /** * Db_Actor 对象 * * @var Aert_Db_Actor */ private $actor; function __construct($dbo) { $this->dbo = $dbo; $this->ds = new Aert_Db_DataSource( $dbo->getPdo() ); $this->actor = new Aert_Db_Actor($this->ds); } /** * 返回数据源对象 * * @return Aert_Db_DataSource */ function getDataSource() { return $this->ds; } /** * 从表中检索符合条件的一条记录 * * @param string $table * @param mixed $cond * @param string $fields * @param string $sort * * @return array */ function selectRow($table ,$cond=null ,$fields='*', $sort=null) { $cond = Aert_Db_SqlHelper::parseCond($this->ds,$cond); if ($cond) $cond = "WHERE {$cond}"; if ($sort) $sort = "ORDER BY {$sort}"; $qfields = Aert_Db_SqlHelper::qfields($fields,$table); return $this->actor->read(Aert_Db_Actor::MODE_READ_GETROW, array( "SELECT {$qfields} FROM {$table} {$cond} {$sort}" )); } /** * 从表中检索符合条件的多条记录 * * @param string $table * @param mixed $cond * @param string $fields * @param string $sort * @param int|array $limit 数组的话遵循格式 ( offset,length ) * @param bool $calc_total 计算总个数 * * @return array */ function select($table, $cond=null, $fields='*', $sort=null, $limit=null, $calc_total=false) { $cond = Aert_Db_SqlHelper::parseCond($this->ds,$cond); if ($cond) $cond = "WHERE {$cond}"; if ($sort) $sort = "ORDER BY {$sort}"; $qfields = Aert_Db_SqlHelper::qfields($fields,$table); $table = Aert_Db_SqlHelper::qtable($table); return $this->actor->read(Aert_Db_Actor::MODE_READ_GETALL, array( "SELECT {$qfields} FROM {$table} {$cond} {$sort}", empty($limit) ? false : $limit, $calc_total )); } /** * 统计符合条件的记录的总数 * * @param string $table * @param mixed $cond * @param string|array $fields * @param boolean $distinct * * @return int */ function count($table, $cond=null, $fields='*', $distinct=false) { if ($distinct) $distinct = 'DISTINCT '; $cond = Aert_Db_SqlHelper::parseCond($this->ds,$cond); if ($cond) $cond = "WHERE {$cond}"; if (is_null($fields) || trim($fields) == '*') { $fields = '*'; } else { $fields = Aert_Db_SqlHelper::qfields($fields,$table); } $table = Aert_Db_SqlHelper::qtable($table); return (int) $this->actor->read(Aert_Db_Actor::MODE_READ_GETONE, array( "SELECT COUNT({$distinct}{$fields}) FROM {$table} {$cond}" )); } /** * 插入一条记录 * * @param string $table * @param array $row * @param bool $pkval 是否获取插入的主键值 * * @return mixed */ function insert($table, array $row, $pkval=false) { list($holders, $values) = Aert_Db_SqlHelper::placeholder($row); $holders = implode(',', $holders); $fields = Aert_Db_SqlHelper::qfields(array_keys($values)); $table = Aert_Db_SqlHelper::qtable($table); return $this->actor->write(Aert_Db_Actor::MODE_WRITE_INSERT, array( Aert_Db_SqlHelper::bind($this->ds, "INSERT INTO {$table} ({$fields}) VALUES ({$holders})", $row), $pkval )); } /** * 更新表中记录 * * @param string $table * @param array $row * @param mixed $cond 条件 * * @return int */ function update($table, array $row, $cond=null) { if ( empty($row) ) return false; list($pairs, $values) = Aert_Db_SqlHelper::placeholderPair($row); $pairs = implode(',', $pairs); $table = Aert_Db_SqlHelper::qtable($table); $sql = Aert_Db_SqlHelper::bind($this->ds, "UPDATE {$table} SET {$pairs}", $row); $cond = Aert_Db_SqlHelper::parseCond($this->ds, $cond); if ($cond) $sql .= " WHERE {$cond}"; return $this->actor->write(Aert_Db_Actor::MODE_WRITE_UPDATE, array( $sql )); } /** * 删除 表中记录 * * @param string $table * @param mixed $cond * * @return int */ function del($table, $cond=null) { $cond = Aert_Db_SqlHelper::parseCond($this->ds, $cond); $table = Aert_Db_SqlHelper::qtable($table); $sql = "DELETE FROM {$table} " . (empty($cond) ? '' : "WHERE {$cond}"); return $this->actor->write(Aert_Db_Actor::MODE_WRITE_DELETE, array( $sql )); } /** * 向表中 某字段的值做 "加"运算 * * @param string $table * @param string $field * @param int $incr * @param mixed $cond * * @return int */ function incrField($table, $field, $incr=1, $cond=null) { if ( empty($field) ) return false; $table = Aert_Db_SqlHelper::qtable($table); $field = Aert_Db_SqlHelper::qfield($field); $sql = "UPDATE {$table} SET {$field}={$field}+{$incr}"; $cond = Aert_Db_SqlHelper::parseCond($this->ds, $cond); if ($cond) $sql .= " WHERE {$cond}"; return $this->actor->write(Aert_Db_Actor::MODE_WRITE_UPDATE, array( $sql )); } } class Aert_Db_Actor { /** * 读 记录集 */ const MODE_READ_GETALL = 1; /** * 读 第一条记录 */ const MODE_READ_GETROW = 2; /** * 读 第一条记录的第一个字段 */ const MODE_READ_GETONE = 3; /** * 读 记录集的指定列 */ const MODE_READ_GETCOL = 4; /** * 读 记录集的总个数 */ const MODE_READ_ALLCOUNT = 5; /** * 写 (插入) 操作 */ const MODE_WRITE_INSERT = 11; /** * 写 (更新) 操作 */ const MODE_WRITE_UPDATE = 12; /** * 写 (删除) 操作 */ const MODE_WRITE_DELETE = 13; /** * 数据源对象 * * @var Aert_Db_DataSource */ private $ds; function __construct(Aert_Db_DataSource $ds) { $this->ds = $ds; } /** * 执行 读 操作 * * @param string $mode 模式 [MODE_READ_GETALL,MODE_READ_GETROW,MODE_READ_GETONE,MODE_READ_GETCOL] * @param mixed $arguments 参数[不同模式参数不同,缺省为sql字符串] * @param callback $cb 查询记录集的回调处理函数 * * @return mixed */ function read($mode, $arguments, $cb=NULL){ $arguments = (array) $arguments; $sql = array_shift($arguments);// 缺省第一个参数是sql字符串 switch ($mode){ case self::MODE_READ_GETALL: // array(sql,limit,counter),如果sql里面带了limit则不能使用counter $limit = array_shift($arguments); $counter = array_shift($arguments); $result = null; if ($counter) { $result = array( 'total' => $this->ds->count($sql), ); } if ($limit) $sql = $this->ds->sql_limit($sql, $limit); if (is_array($result)) { $result['rows'] = ($result['total'] == 0) ? array() : $this->ds->all($sql); } else { $result = $this->ds->all($sql); } break; case self::MODE_READ_GETCOL:// array(sql,col,limit,counter) col 下标从 0开始 为第一列 $col = (int) array_shift($arguments); $limit = array_shift($arguments); $counter = array_shift($arguments); $result = null; if ($counter) { $result = array( 'total' => $this->ds->count($sql), ); } if ($limit) $sql = $this->ds->sql_limit($sql, $limit); if (is_array($result)) { $result['rows'] = ($result['total'] == 0) ? array() : $this->ds->col($sql,$col); } else { $result = $this->ds->col($sql,$col); } break; case self::MODE_READ_GETROW: $result = $this->ds->row($sql); break; case self::MODE_READ_GETONE: $result = $this->ds->one($sql); break; case self::MODE_READ_ALLCOUNT: $result = $this->ds->count($sql); break; default: throw Exception("无效[r]: {$mode}"); } return (empty($cb) || !is_callable($cb)) ? $result : call_user_func_array($cb,array($result)); } /** * 执行 更新/删除 操作 * * @param string $mode 模式 [MODE_WRITE_INSERT,MODE_WRITE_UPDATE,MODE_WRITE_DELETE] * @param mixed $arguments 参数[不同模式参数不同,缺省为sql字符串] * @param callback $cb 查询结果集的回调处理函数 * * @return mixed */ function write($mode, $arguments, $cb=NULL){ $arguments = (array) $arguments; $sql = array_shift($arguments);// 缺省第一个参数是sql字符串 $this->ds->execute($sql); switch ($mode){ case self::MODE_WRITE_INSERT: // 插入操作可选 得到主键标识 $id = array_shift($arguments); $result = $id ? $this->ds->insert_id() : $this->ds->affected_rows(); break; case self::MODE_WRITE_UPDATE: case self::MODE_WRITE_DELETE: $result = $this->ds->affected_rows(); break; default: throw Exception("无效[w]: {$mode}"); } return (empty($cb) || !is_callable($cb)) ? $result : call_user_func_array($cb,array($result)); } } /** * Db 数据源 */ class Aert_Db_DataSource { /** * @var int */ private $query_count = 0; /** * @var PDO */ private $db; /** * @var int */ protected $affected_rows = 0; function __construct(PDO $db) { $this->db = $db; } function begin() { $this->db->beginTransaction(); } function commit() { $this->db->commit(); } function rollback() { $this->db->rollBack(); } function qstr($value) { if (is_int($value) || is_float($value)) { return $value; } if (is_bool($value)) { return $value ? 1 : 0; } if (is_null($value)) { return 'NULL'; } return $this->db->quote($value); } function insert_id() { return $this->db->lastInsertId(); } function affected_rows() { return $this->affected_rows; } function execute($sql, array $args = null) { $this->affected_rows = 0; if (!empty($args)) { $sql = Aert_Db_SqlHelper::bind($this, $sql, $args); } Log::debug($sql); $result = $this->db->exec($sql); $this->query_count++; if ($result === false) { $error = $this->db->errorInfo(); throw new Exception("QUERY_FAILED: {$error[0]}/{$error[1]}, {$error[2]}\n{$sql}"); } $this->affected_rows = $result; } /** * @return PDOStatement */ private function query($sql) { Log::debug($sql); $statement = $this->db->query($sql); $this->query_count++; if ($statement !== false) return $statement; $error = $this->db->errorInfo(); throw new Exception("QUERY_FAILED: {$error[0]}/{$error[1]}, {$error[2]}\n{$sql}"); } function all($sql) { $res = $this->query($sql); /* @var $res PDOStatement */ $rowset = $res->fetchAll(PDO::FETCH_ASSOC); $res = null; return $rowset; } function one($sql) { $res = $this->query($sql); /* @var $res PDOStatement */ $val = $res->fetchColumn(0); $res = null; return $val; } function row($sql) { $res = $this->query($sql); /* @var $res PDOStatement */ $row = $res->fetch(PDO::FETCH_ASSOC); $res = null; return $row; } function col($sql, $col=0) { $res = $this->query($sql); /* @var $res PDOStatement */ $rowset = $res->fetchAll(PDO::FETCH_ASSOC,$col); $res = null; return $rowset; } function count($sql) { return (int) $this->one("SELECT COUNT(*) FROM ( $sql ) AS t"); } function sql_limit($sql, $limit) { if (empty($limit)) return $sql; if (is_array($limit)) { list($skip, $l) = $limit; $skip = intval($skip); $limit = intval($l); } else { $skip = 0; $limit = intval($limit); } return "{$sql} LIMIT {$skip}, {$limit}"; } } class Aert_Db_SqlHelper { /** * 根据 SQL 语句和提供的参数数组,生成最终的 SQL 语句 * * @param Aert_Db_DataSource $ds * @param string $sql * @param array $inputarr * * @return string */ static function bind(Aert_Db_DataSource $ds, $sql, array $inputarr) { $arr = explode('?', $sql); $sql = array_shift($arr); foreach ($inputarr as $value) { if (isset($arr[0])) { $sql .= $ds->qstr($value) . array_shift($arr); } } return $sql; } /** * 解析查询条件 * * @param Aert_Db_DataSource $ds * @param mixed $cond * @param bool $dash 是否使用括号将返回的条件包括起来 * * @return string */ static function parseCond(Aert_Db_DataSource $ds, $cond, $dash=false) { if (empty($cond)) return ''; // 如果是字符串,则假定为自定义条件 if (is_string($cond)) return $cond; // 如果不是数组,说明提供的查询条件有误 if (!is_array($cond)) return ''; static $equalIN = array('=','IN','NOT IN'); static $betweenAnd = array('BETWEEN_AND','NOT_BETWEEN_AND'); $where = '';$expr = ''; /** * 不过何种条件形式,一律为 字段名 => (值, 操作, 连接运算符, 值是否是SQL命令) 的形式 */ foreach ($cond as $field => $d) { $expr = 'AND'; if (!is_string($field)) { continue; } if (!is_array($d)) { // 字段名 => 值 $d = array($d); } reset($d); // 第一个元素是值 if (!isset($d[1])) { $d[1] = '='; } if (!isset($d[2])) { $d[2] = $expr; } if (!isset($d[3])) { $d[3] = false; } list($value, $op, $expr, $isCommand) = $d; $op = strtoupper(trim($op)); $expr = strtoupper(trim($expr)); if (is_array($value)){ do { if (in_array($op, $equalIN)){ if ($op == '=') $op = 'IN'; $value = '(' . implode(',',array_map(array($ds, 'qstr'),$value)) . ')'; break; } if (in_array($op, $betweenAnd)){ $between = array_shift($value); $and = array_shift($value); $value = sprintf('BETWEEN %s AND %s',$ds->qstr($between),$ds->qstr($and)); $op = 'NOT_BETWEEN_AND' == $op ? 'NOT' : '';// 此处已经串在 $value 中了 break; } // 一个字段对应 多组条件 的实现,比如 a > 15 OR a < 5 and a != 32 // 'a' => array( array( array(15,'>','OR'),array(5,'<','AND'), array(32,'!=') ) , 'FIELD_GROUP') if ($op == 'FIELD_GROUP'){ $kv = array(); foreach($value as $k => $v){ $kv[":+{$k}+:"] = $v; } $value = self::parseConditions($ds,$kv,true); foreach(array_keys($kv) as $k){ $value = str_ireplace($k,$field,$value); } $field = $op = '';// 此处已经串在 $value 中了 break; } } while(false); $isCommand = true; } if (!$isCommand) { $value = $ds->qstr($value); } $where .= "{$field} {$op} {$value} {$expr} "; } $where = substr($where, 0, - (strlen($expr) + 2)); return $dash ? "({$where})" : $where; } static function qtable($table) { return "`{$table}`"; } static function qfield($fieldName, $table = null) { $fieldName = ($fieldName == '*') ? '*' : "`{$fieldName}`"; return $table != '' ? self::qtable($table) . '.' . $fieldName : $fieldName; } static function qfields($fields, $table = null, $returnArray = false) { if (!is_array($fields)) { $fields = explode(',', $fields); $fields = array_map('trim', $fields); } $return = array(); foreach ($fields as $fieldName) { $return[] = self::qfield($fieldName, $table); } return $returnArray ? $return : implode(', ', $return); } static function placeholder(& $inputarr, $fields = null) { $holders = array(); $values = array(); if (is_array($fields)) { $fields = array_change_key_case(array_flip($fields), CASE_LOWER); foreach (array_keys($inputarr) as $key) { if (!isset($fields[strtolower($key)])) { continue; } $holders[] = '?'; $values[$key] =& $inputarr[$key]; } } else { foreach (array_keys($inputarr) as $key) { $holders[] = '?'; $values[$key] =& $inputarr[$key]; } } return array($holders, $values); } static function placeholderPair(& $inputarr, $fields = null) { $pairs = array(); $values = array(); if (is_array($fields)) { $fields = array_change_key_case(array_flip($fields), CASE_LOWER); foreach (array_keys($inputarr) as $key) { if (!isset($fields[strtolower($key)])) { continue; } $qkey = self::qfield($key); $pairs[] = "{$qkey}=?"; $values[$key] =& $inputarr[$key]; } } else { foreach (array_keys($inputarr) as $key) { $qkey = self::qfield($key); $pairs[] = "{$qkey}=?"; $values[$key] =& $inputarr[$key]; } } return array($pairs, $values); } }
<?php /** * AertDb表模型 CRUD 包装器 * * @author xuxiaohan */ class Aert_TObject { /** * 数据库链接节点名 * * 子类可以覆盖此属性 * * @var string */ protected $queryNode = ''; /** * 数据表名 * * 子类可以覆盖此属性 * * @var string */ protected $table; /** * 返回 对象实例 * * @param string $table * @param string $query_node * * @return Aert_TObject */ static function instance($table,$query_node='') { static $list = array(); $table = trim($table); if ( empty($table) ) return null; if (empty($list[$table])) { $list[$table] = new self(); $list[$table]->queryNode = $query_node; $list[$table]->table = $table; } return $list[$table]; } /** * 从表中检索符合条件的多条记录 * * @param mixed $cond * @param string $fields * @param string $sort * @param int|array $limit 数组的话遵循格式 ( offset,length ) * @param bool $calc_total 计算总个数 * * @return array */ function getAll($cond=null, $fields='*', $sort=null, $limit=null, $calc_total=false) { return Aert_DbRepo::queryNode($this->queryNode)->select($this->table,$cond, $fields, $sort, $limit, $calc_total); } /** * 从表中检索符合条件的一条记录 * * @param mixed $cond * @param string $fields * @param string $sort * * @return array */ function getOne($cond=null ,$fields='*', $sort=null) { return Aert_DbRepo::queryNode($this->queryNode)->selectRow($this->table,$cond, $fields, $sort); } /** * 统计符合条件的记录的总数 * * @param mixed $cond * @param string|array $fields * @param boolean $distinct * * @return int */ function count($cond=null, $fields='*', $distinct=false) { return Aert_DbRepo::queryNode($this->queryNode)->count($this->table,$cond, $fields, $distinct); } /** * 插入一条记录 * * @param array $row * @param bool $pkval 是否获取插入的主键值 * * @return mixed */ function insert(array $row, $pkval=false) { return Aert_DbRepo::queryNode($this->queryNode)->insert($this->table, $row, $pkval); } /** * 更新表中记录,返回表中被更新行数 * * @param array $row * @param mixed $cond 条件 * * @return int */ function update(array $row, $cond=null) { return Aert_DbRepo::queryNode($this->queryNode)->update($this->table, $row, $cond); } /** * 删除 表中记录,返回表中被删除行数 * * @param mixed $cond * * @return int */ function del($cond=null) { return Aert_DbRepo::queryNode($this->queryNode)->del($this->table, $cond); } /** * 向表中 某字段的值做 "加"运算 * * @param string $field * @param int $incr * @param mixed $cond * * @return int */ function incrField($field, $incr=1, $cond=null) { return Aert_DbRepo::queryNode($this->queryNode)->incrField($this->table, $field, $incr, $cond); } /** * 向表中 某字段的值做 "减"运算 * * @param string $field * @param int $incr * @param mixed $cond * * @return int */ function decrField($field, $decr=1, $cond=null) { return Aert_DbRepo::queryNode($this->queryNode)->incrField($this->table, $field, (-1 * $decr), $cond); } }
功能虽然木有那么强大,但是也应该能方便不少
相关推荐
此外,还有许多其他工具和服务支持FirePHP格式的数据,如Chrome的Firbug Lite扩展,使得跨浏览器的调试成为可能。 **优化调试体验** 为了充分利用FirePHP,开发者可以自定义输出的格式和样式,设置调试级别,以及...
标题中的"FirePHP.class_aif4xw_FirePHP_"似乎是一个类文件或者与FirePHP扩展有关的标识符。FirePHP是PHP开发中一个流行的调试工具,它允许开发者在Firefox浏览器的Firebug插件中查看PHP运行时的信息,如变量值、...
【FirePHP.class_y4fyqx_FirePHP_】是一个基于PHP的服务器端脚本实现,主要目的是为了在开发过程中提供方便的调试工具。FirePHP是一个知名的PHP扩展,它允许开发者在浏览器的Firefox浏览器中通过Firebug插件查看PHP...
1. "FirePHP.class.php" - 这个文件很可能是FirePHP库的核心类文件,包含了FirePHP的函数和方法定义,用于在PHP代码中启用和使用FirePHP的功能。 2. "ed0c48f58968d4167ef5f4a6315eaf17.txt" - 这个文件可能是一个...
在浏览器中,确保已经启用FirePHP插件,然后刷新包含这些调试语句的页面。在Chrome的开发者工具或Firefox的Firebug中,你会看到一个新的“FirePHP”标签页,其中包含了所有发送的调试信息。 **6. 高级用法** - **...
4. **数据库查询调试**:与数据库交互时,FirePHP能展示SQL查询及其结果,便于检查查询是否正确并优化SQL语句。 5. **HTTP请求和响应分析**:显示每个HTTP请求和响应的详细信息,包括头信息、cookies和POST数据,这...
firephp 这个开发工具很实用,在浏览器上如何调试php代码。现在给大家分享一个文件,实在谷歌浏览器上用的firephp插件。里面有个readme文件有详细的配置过程,希望对大家有帮助
4. **使用FirePhp调试**:在PHP代码中,当需要调试时,只需调用FirePhp的相关方法,这些信息就会在浏览器的Firebug控制台中显示。这样,你可以实时查看变量状态,追踪代码执行流程,甚至监控SQL查询。 **FirePhp的...
标题中的"FirePHP.class_tgwet8_FirePHP_"似乎是一个类名,它可能是FirePHP扩展在特定项目中的实现或自定义版本。FirePHP是一个PHP调试工具,它允许开发者通过浏览器的JavaScript接口发送PHP变量、堆栈跟踪和性能...
这个标题 "FirePHP.class_2n0k3l_FirePHP_" 暗示了我们正在处理的是 FirePHP 类库的一个版本或组件,可能是一个特定的类文件或模块。 FirePHP.class.php 是核心的类文件,很可能包含了 FirePHP 的主要功能实现,如...
5. **自定义数据类型支持**:除了基本的数据类型,FirePHP 还支持自定义数据类型,如用户定义的类实例,使调试更全面。 6. **跨框架兼容性**:FirePHP 是一个独立的库,可以与各种 PHP 框架(如 Laravel, Symfony, ...
"FirePHP.class_05leb0_FirePHP_" 提供了一种高效的方法来实现这一目标。这个命名可能暗示着它是一个实现了FirePHP接口的类,FirePHP是一个流行的PHP调试工具,它允许开发者通过Firefox浏览器的Firebug扩展来查看PHP...
在标题"up_174939_FirePHP.class_4peiw.rar"中,我们可以推测这是与FirePHP相关的源码压缩包,可能包含了核心类库和其他辅助文件。 【FirePHP.class.php】是FirePHP的主要类文件,其中包含了FirePHP的核心功能实现...
首先,要启用FirePHP,你需要确保已经安装了【Zend Framework】。Zend Framework是PHP的一个开源应用框架,它提供了一系列的工具和服务,为构建高质量的Web应用程序提供了基础。在安装FirePHP之前,需要先安装Zend ...
4. **配置浏览器插件** - 最后,在谷歌浏览器中安装FirePHP的配套插件,如Firefox的Firebug(现在已经不再更新,但旧版本仍然可用)和Chrome的Web Developer Tools。这样,你就可以在浏览器的控制台看到发送的调试...
4. 设置Firebug:在Firefox浏览器中,确保已经安装并启用了Firebug插件。在Firebug的控制台选项中启用FirePHP,这样就可以在浏览器中看到来自Magento的调试信息。 5. 测试和优化:现在,当你在Magento中执行任何...
firefox最经典的49.0版本,支持firebug的最后一个版本,完美支持firephp。开发调试php神奇
在实际使用中,FirePHP通过HTTP头信息将调试数据发送到浏览器,只有当用户安装了Firebug扩展并且启用了FirePHP插件时,这些信息才会显示出来。这样既不会影响非开发者用户的体验,又能让开发者在实时环境中调试代码...
4. **Time Profiling**:测量代码段的执行时间,帮助找出性能瓶颈。 5. **Exceptions**:捕获并显示PHP异常,便于快速定位错误。 6. **Watches**:监视特定变量的变化,观察它们在程序运行中的动态。 使用FirePHP时...