PHP OOP困境:如何保持数据库连接';在';类对象?
我又来了!;) 我正在开发(嗯,我还在计划阶段)一个web应用程序,我会让其他开发者有可能编写自己的插件/模块(就像CMS、drupal、joomla等) 我的问题是,出于许多原因(首先是数据完整性),我不得不迫使开发人员使用我为与数据库交互而编写的方法。我不需要对数据库结构保密,但如果可能的话,我很感激 总之,我的目标是:PHP OOP困境:如何保持数据库连接';在';类对象?,php,mysql,database,oop,postgresql,Php,Mysql,Database,Oop,Postgresql,我又来了!;) 我正在开发(嗯,我还在计划阶段)一个web应用程序,我会让其他开发者有可能编写自己的插件/模块(就像CMS、drupal、joomla等) 我的问题是,出于许多原因(首先是数据完整性),我不得不迫使开发人员使用我为与数据库交互而编写的方法。我不需要对数据库结构保密,但如果可能的话,我很感激 总之,我的目标是: 保持“受保护”且不可从我的类外部访问数据库连接 如果可能(但应该是第1点的结果),对真实的数据库结构保密 插件/模块行为将像Drupal钩子一样实现 下面是我目前处境的一个
<?php
// File dbclass.php
class DbHandler{
/*
* As simply as i could ;)
*/
private $dbLink;
public function __construct(){
$this->dbLink = pg_connect("host=127.0.0.1 user=myuser password=mypassword dbname=mydatabase");
}
public function __destruct(){
pg_close($this->dbLink);
unset($this->dbLink);
}
}
?>
我在postgresql上运行,但我想Mysql上的问题也是一样的
就我所想,我能做的唯一方法是在调用所有模块钩子之前关闭连接,然后每次钩子需要损坏数据库时重新打开并重新关闭连接。但我真的不喜欢这个解决方案,因为它效率不高
如果有人有更好的想法,请与我分享
p、 s:我的英语很差,我希望问题很清楚
编辑:奇怪的解决方案似乎对我来说是最好的:打开并立即关闭重影连接将阻止下一次pg_*或mysql_*函数调用。
这个解决方案,再加上使用自定义名称重命名pg_*或mysql_*函数,将(我认为)绝对避免模块/插件对数据库的任何不受控制的访问。也许您听说过,这可能适合您的需要。其思想是实际创建数据库对象的代理实例,其行为与实际数据库完全相同。因此,您的真实数据库对其他人是隐藏的,只有您的decorator对象知道在哪里可以找到真实的数据库。这有点像黑客,但是: 在进行pg_connect调用后,可以立即使用一些无用参数调用pg_connect。它将失败,但请查看它是否也覆盖默认连接,以防止其他人在pg_查询中使用它 编辑:事实证明(参见注释),使用dud参数调用pg_connect不会覆盖默认连接 以下是计划B(未经测试):
这将创建到数据库的第二个连接,但会立即将其关闭。我严重怀疑这会使默认参数恢复到第一次连接。Hm,也许您可以在DB级别解决这个问题 在数据库上可以有两个用户帐户。一个具有适当权限的,称为
app main
或您连接的东西,另一个没有权限的,称为app plugin
。然后,您可以这样调用您的插件:
pg_query("SET ROLE app-plugin;"); //precaution--use low-privilege-user
$plugin->doStuff();
pg_query("SET ROLE NONE;"); //Reset role back to default
这将使当前会话的权限降低到应用程序插件
-用户的权限。当然,插件可以调用“SET ROLE NONE;
”来再次提升权限,所以它不是“安全的”。这只是一种预防措施。但连接至少会保持活动状态,正常查询将失败。(当然,如果插件在一个会话中被调用50次,可能会影响性能……谁知道呢?)
无论如何,我从来没有尝试过这个mysqlf,所以我对此一无所知,真的
文档:我可能遗漏了一些东西,但是只要用户能够阅读您的代码,他们就可以复制和粘贴建立自己连接所需的信息。你真的允许用户连接到你的数据库吗 假设它位于已启用模块的函数/挂钩内 这是我想要避免的行为 选择*
这不是你的问题。我猜用户将在他们自己的环境/数据库中托管您的应用程序,因此,当您提供更好的替代方案时,他们会受到不良做法的损害。想到两个选项:
pg.*
API黑客喜欢打开/关闭哑DB连接将工作,但我会认为这是最后的手段。< /P>
听起来您希望确保系统及其插件的质量。我认为这些黑客无法达到这个目的。毫无疑问,我在这里做了一些假设,但总的来说,我认为最好的方法是向插件作者提供可靠的示例/标准和良好的文档。如果您将为插件托管一个权威的存储库,那么您还可以扫描它们的代码,查看是否存在这样的违规行为,并建议维护人员对其进行修复。DaNieL的问题似乎是希望封装数据库连接,但PHP的pg_查询功能不需要提供连接。如果省略,则使用创建的最后一个连接。这为访问封装的数据库连接提供了一个后门。哇,我的问题在三行文字中,你得到了要点,伙计!您必须实现get_all方法,该方法将从database@streetparade:我发布的代码只是一个例子。。。缺少整个用户类!;)我只是想指出,如果你正在对插件进行沙箱处理,你实际上并不需要ghost连接。就沙箱而言,白名单比黑名单要好得多。我没有使用Runkit,但它似乎只能被列入黑名单。另外,重命名函数是不够的,您可能需要查看Runkit_沙盒。我仍然会对此犹豫不决。如果安全是最重要的,那么试着找到一种采用白名单方法的方法。e、 g.插件使用嵌入式语言,或其他人建议的HTTP API,或应用程序
$users = new User();
$users -> get_all();
$this->dbLink = pg_connect("host=127.0.0.1 user=myuser password=mypassword dbname=mydatabase");
$junkConnection = pg_connect("host=127.0.0.1 user=myuser password=mypassword dbname=mydatabase");
pg_close($junkConnection);
pg_query("SET ROLE app-plugin;"); //precaution--use low-privilege-user
$plugin->doStuff();
pg_query("SET ROLE NONE;"); //Reset role back to default