我有一个自定义的CMS系统,我已经写在PHP。我几乎完成了将所有旧的遗留mysql_函数转换为PDO。但是,我在一个文件中有大量的函数,没有类包装器。文件中只有大约50个函数,这实际上是运行CMS所需的所有函数。很多天前,我养成了这样使用全局值的坏习惯:
function getWidgets($widget_id){
global $db, $BLOG_ID;
$stmt = $db->prepare("SELECT * FROM widget_assoc WHERE bid=? AND aid=?");
$stmt->execute(array($BLOG_ID, $widget_id));
$matches = $stmt->rowCount();
if($matches !== 0){
for($i = 0; $path[$i] = $stmt->fetch(); $i++) ;
array_pop($path);
return $path;
}
}
你可以用不同的方法来解决这个问题,这取决于你想花多少时间来做它,以及你想做得有多“好”。
您可以让方法保持它们假设正常工作的方式。正如你关于不想重写一切的评论,这可能是你最好的方法。
归根结底,在所有的函数中使用全局变量(在我看来)和一个包含50个独立函数而没有类的文件一样糟糕。
一个实际的例子可能是这样的:
/**
* Handle your database connection, querying etc functions
*/
class DB {
protected $_pdo;
public function getPdo() {
if (is_null($this->pdo)) {
$this->_pdo = new PDO(...);
}
return $this->_pdo;
}
public function __construct() {
return $this->getPdo();
}
public function query($sql, $binds = []) {
// write a function that executes the $sql statement on the
// PDO property and return the result. Use $binds if it is not
// empty
$eg = $this->getPdo()->prepare($sql);
return $eg->execute((array) $binds);
}
/**
* Create a basic framework for all purpose-classes to extend
*/
abstract class Base {
/**
* "DB" property might be broad here to cover other DBs or connection
* methods (in theory)
*/
protected $_db;
public function __construct() {
$this->_db = new DB;
}
public function db($sql, $binds) {
return $this->_db->query($sql, $binds);
}
// insert other common methods here that all type-specific classes
// can use
}
现在执行一个具体的行动/角色:
class Blog extends Base {
public function get($blogId = null) {
// Basic error check
if (empty($blogId)) {
throw new UnexpectedValueException('Blog post ID was missing!');
}
return $this->db('SELECT * FROM `blogposts` WHERE blog_id = ?', $blogId);
}
}
注我还没有测试过这个,但是现在的原则是Blog类只包含特定于Blog文章的逻辑。任何格式化函数、安全函数等可以在基类中,也可以在基类类似于DB使用的另一个辅助类中,例如格式化程序类。
<?php
# blogPost.php
# - Gets a blog post
require_once 'common.php'; // <--- include your class files, or an autoloader
// Instantiate the class for this role
$blog = new Blog;
// Get the blog post
$id = (isset($_GET['id'])) ? (int) $_GET['id'] : null;
$post = $blog->get($id);
// now other methods:
$post->toHTML(); // example - function might call a template file, insert the
// DB results into it and output it to the browser
class Common {
protected static $_db;
protected static $_blogId;
public function getDb() {
if (is_null(static::$_db)) {
static::$_db = new PDO(...);
}
return static::$_db;
}
public static function getBlogId() {
return (int) static::$_blogId;
}
public static function setBlogId($id) {
static::$_blogId = (int) $id;
}
}
现在您只需要在开始调用函数之前实例化这个类,并设置blog post ID(如果需要的话)。只要需要,PDO连接就会被懒洋洋地创建。
# functions.php
require_once 'common.php';
function getWidgets($widget_id) {
$stmt = Common::getDb()->prepare('SELECT * FROM widget_assoc WHERE bid = ? AND aid = ?');
$stmt->execute(array(Common::getBlogId(), $widget_id));
$matches = $stmt->rowCount();
if ($matches !== 0) {
for($i = 0; $path[$i] = $stmt->fetch(); $i++);
array_pop($path);
return $path;
}
}
您在这里的唯一责任是在每一页上设置博客文章ID,例如:
# blogPost.php
require_once 'common.php';
// Manual dependency blog ID needs to be set before processing:
$blogId = isset($_GET['blog_id']) ? (int) $_GET['blog_id'] : null;
Common::setBlogId($blogId);
// now you call your processing methods and perform your logic flow
全局函数 返回上级 DirectDrawCreate DirectDrawCreateClipper DirectDrawEnumerate DirectDrawEnumerateEx DirectDrawCreate 返回目录 创建一个DirectDraw对象的实例。 HRESULT WINAPI DirectDrawCreate( GUID FAR *lpGUID, LPDIRECTDRAW
debug 调试打印PHP变量,并中断执行。等同于 var_dump($var1, $var2);die; table 将任意MySQL表构造成Model对象。 table($table_name, $db_object_id); model 创建模型对象。 model($model_name, $db_object_id);
Herosphp提供了一些全局辅助函数: //格式化打印变量(数据) __print($message); //终端高亮打印绿色(success) tprintOk($message); //终端高亮打印红色(error) tprintError($message); //终端高亮打印黄色(warning) tprintWarning($message); //计算字符串的hash值, 默
imigo 启动一个协程,自动创建和销毁上下文 imigo(function(){ $value = Redis::get('key'); // 无需手动释放任何资源 }); 传入参数: imigo(function($id, $name){ echo $id, ':', $name, PHP_EOL; // 1:test }, 1, 'test'); imiCalla
问题内容: 什么是效用全球关键字? 有什么理由偏爱一种方法而不是另一种方法? 安全? 性能? 还要别的吗? 方法1: 方法2: 什么时候使用有意义? 对我来说,这似乎很危险 ……但可能只是缺乏知识。我对 文档化的 技术原因感兴趣(例如,带有示例代码,链接到文档…)。 提前致谢! 赏金 这是关于该主题的一个很好的一般性问题,我(@Gordon)会提供赏金以获取其他答案。您的答案是否与我的意见一致或给
MiniFramework 在初始化时,会自动加载一个全局函数库,你可以随时调用里面的全局函数,例如: $test = array('a', 'b', 'c'); //调用全局函数 pushJson() 输出一个 JSON 串并终止程序运行 pushJson($test); 提示:全局函数库位于 Mini/Functions/Global.func.php