Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP OOP困境:如何保持数据库连接';在';类对象?_Php_Mysql_Database_Oop_Postgresql - Fatal编程技术网

PHP OOP困境:如何保持数据库连接';在';类对象?

PHP OOP困境:如何保持数据库连接';在';类对象?,php,mysql,database,oop,postgresql,Php,Mysql,Database,Oop,Postgresql,我又来了!;) 我正在开发(嗯,我还在计划阶段)一个web应用程序,我会让其他开发者有可能编写自己的插件/模块(就像CMS、drupal、joomla等) 我的问题是,出于许多原因(首先是数据完整性),我不得不迫使开发人员使用我为与数据库交互而编写的方法。我不需要对数据库结构保密,但如果可能的话,我很感激 总之,我的目标是: 保持“受保护”且不可从我的类外部访问数据库连接 如果可能(但应该是第1点的结果),对真实的数据库结构保密 插件/模块行为将像Drupal钩子一样实现 下面是我目前处境的一个

我又来了!;)

我正在开发(嗯,我还在计划阶段)一个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,所以我对此一无所知,真的

    文档:

    我可能遗漏了一些东西,但是只要用户能够阅读您的代码,他们就可以复制和粘贴建立自己连接所需的信息。你真的允许用户连接到你的数据库吗

    假设它位于已启用模块的函数/挂钩内

    这是我想要避免的行为

    选择*


    这不是你的问题。我猜用户将在他们自己的环境/数据库中托管您的应用程序,因此,当您提供更好的替代方案时,他们会受到不良做法的损害。

    想到两个选项:

  • 在文档/标准中而不是在代码中强制执行这一点(听起来这对于您的案例来说是不够的?)

  • 使用PDO pgsql而不是
    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