duanhuang2150 2017-02-08 19:19
浏览 72
已采纳

在PHP中,我们需要在所有文件中包含还是有更好的方法?

I have a DB configuration (db.php) in the root folder

MySQL with PDO_MYSQL

$host = "";
$user = "";
$pass = "";
$dbname = "";
# connect to the database
$DBH = new PDO("mysql:host=$host;port=3306;dbname=$dbname", $user, $pass,array(PDO::ATTR_PERSISTENT => true));
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

I figured that if I need a DB connection I would need to do

<?php
include '../../db.php';

In all the PHP files that need the DB connection.

My question is do I need to do "include" everytime I need a DB connection or is there a way to set this connections setting Global so I can just call $DBH->prepare(SQLSTATEMENT) any where in the project and it will work.

Or is there a better way to handle DB connection settings?

  • 写回答

1条回答 默认 最新

  • dongyanpai2701 2017-02-08 20:01
    关注

    The short answer: Yes, you need to include your DB file in every page that uses it.

    The long answer... PHP doesn't load every PHP file in existence every time a script is run, so it has to know where your variables/classes are coming from. However, there are a couple of ways to not have to include the db file each time. Your options for this are that you can auto-prepend the file, you can have your file included from another file that already has the db variable set up, or you can set your code up in an OO manner and include an autoload file.

    auto-prepend

    If every file you have on this server needs to access the database AND you have access to the php.ini file, you can set the auto-prepend-file option in your php.ini. This will automatically include the file in every file as if loaded by require. If you go this route, make sure you are checking in your db file if it's already been loaded:

    your-db-file.php

    if (!defined('MYPROJECT_DB_FILE_LOADED')) {
        define('MYPROJECT_DB_FILE_LOADED', true);
        // load DBH and stuff here.
    }
    

    include from another file

    Another good option that doesn't require you messing with the php.ini file is to structure your code in a way that your php files are loaded from a parent file. A great example of this is how WordPress handles loading its pages. WordPress has a main index.php file that checks the URL and loads pages based on the path. Pages included from this file have access to the variables from that file. A simple example of how to set that up could be like this:

    .htaccess in root directory (assuming mod_rewrite is enabled)

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^.* /index.php
    

    This will route everything through your index.php file which could have something like this:

    // Do all of your DBH stuff
    $DBH = ...
    
    $url = trim($_SERVER['REQUEST_URI'], '/');
    if ($url === 'some/path/here') {
        include 'other-file.php';
    }
    

    Then, other-file.php would have access to the DBH variable:

    $DBH->do_something();
    

    use OO (object orientated) design and include autoload

    The most common method (and imho the best) is to structure your code in an OO way and just include the autoload file. A great example of this is how composer installs dependencies into your project and generates a vendor/autoload.php file to be included.

    One simple approach to this would be to namespace your classes, place them all in a directory, and then create an autoload file (using spl_autoload_register). Here is a quick (and untested) example of how you could accomplish that:

    Inside /projectroot/lib for example:

    /projectroot/lib/MyDB.php

    namespace MyProject;
    
    if (!class_exists('\MyProject\MyDB')) {
        class MyDB {
            // Add some DB methods in here.
        }
    }
    

    /projectroot/lib/autoload.php

    if (!defined('MYPROJECT_SPL_AUTOLOAD_REGISTERED')) {
        define('MYPROJECT_SPL_AUTOLOAD_REGISTERED', true);
        spl_autoload_register(function($class) {
            $class = explode($class, '\\');
            if (array_shift($class) === 'MyProject') {
                require __DIR__.'/'.join('/', $class);
            }
        });
    }
    

    Then, from any other file you have:

    require '/projectroot/lib/autoload.php';
    
    $db = new \MyProject\MyDB();
    

    I realize that the last option doesn't stop you from having to use an include in every file, but you always include the same file (so you can copy/paste), AND any class namespaced correctly in your lib folder will automatically be included any time you need it, so it will work with more than just your db stuff.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图