【问题标题】:Denying a PHP class to be inherited or used拒绝继承或使用 PHP 类
【发布时间】:2024-01-21 18:46:01
【问题描述】:

对于我的项目,我创建了一个名为 DBAccess 的文件夹,其中包含所有具有 PHP 类、常量函数等的与数据库相关的 PHP 文件。在文件夹的外部,我创建了一个名为 DBAccess.php 的 php 文件。 以下是我的目录结构简而言之

Project1
  |_DBAccess
  |       |_functions.php
  |       |_class.php
  |       |_constants.php         
  |_DBAccess.php
  |_index.php
  |_aboutus.php  
    .......

现在我希望限制根目录中的任何页面使用 DBAccess 文件夹的内容,但 DBAccess.php 文件除外。在 PHP 中是否可以使用 .htaccess 或其他内容?

【问题讨论】:

  • 为什么?! 一些 PHP 代码必须使用这些文件,否则它们是无用的(字面意思)。只是不要在其他代码中使用这些文件,你不需要那么保护自己。
  • +1,但我很期待知道这个问题的答案!
  • 既然你写了课程和那些页面,那么你可以简单地决定不在你提到的那些页面中包含你的课程,为什么要“保护”
  • 使用不允许扩展类的“​​final class”是您可以限制的。

标签: php .htaccess xampp


【解决方案1】:

你可以这样做:

DebugAccess/foo.php

<?php
$trace = debug_backtrace();

if (isset($trace[0])) {
  $dir =  basename(dirname($trace[0]['file']));
  $file = basename($trace[0]['file']);
  if ($file != 'DBAccess.php' && $dir != 'DBAccess') {
    throw new Exception("Nice try butthead");
  }
}

echo "Access Granted\n";

DBAccess.php

<?php
include_once("DBAccess/foo.php");

NoDBAccess.php

<?php
include_once("DBAccess/foo.php");

> php DBAccess.php 
Access Granted

> php NoDBAccess.php 

Fatal error: Uncaught exception 'Exception' with message 'Nice try butthead' in /Users/seanberry/so/DBAccess/foo.php:7
Stack trace:
#0 /Users/seanberry/so/NoDBAccess.php(3): include_once()
#1 {main}

【讨论】:

  • 真的不希望您的代码可测试(或可重用)?
  • 我刚刚回答了这个问题。我没有提到我认为这是一个的想法,我确实这样做了。
  • 这是一个糟糕问题的正确解决方案。 @sberry 您还应该考虑到 DBAccess 文件夹中的文件可能会调用该文件夹中的其他文件/函数。
【解决方案2】:

您可以创建一个函数来处理这个问题,您所要做的就是在 _DBAccess.php 或您需要访问这些文件的任何其他文件中调用该函数。

试试这个功能:

function include_all_php($folder){
    foreach (glob("{$folder}/*.php") as $filename)
    {
        require $filename;
    }
}

然后您只需使用文件夹名称调用该函数。

include_all_php("_DBAccess")

如果您希望文件不包含这些文件,则不需要它们:)

【讨论】:

    【解决方案3】:
    • .htaccess 与 PHP 无关,它是 Apache Web 服务器的设置文件。 Apache 无法阻止 PHP 代码读取磁盘上的文件。

    • 您可以通过例如要求定义某些常量来防止意外访问:

      // DBAccess.php
      define('CAN_ACCESS_DB', true);
      
      // functions.php
      if( !defined('CAN_ACCESS_DB') ){
          die('You are not allowed to access this file');
      }
      

      ...但是没有办法阻止故意访问。

    您最好的机会可能是重新考虑您的设计。

    【讨论】:

      【解决方案4】:

      是的,你可以:

      a) 通过在 DBAccess.php 中定义一个全局变量,例如

      define('DB_LIB',true)
      

      并在文件夹中的所有其他文件中使用 DB_LIB 常量

      (有点小技巧,但这可以确保不会直接脱离上下文访问这些文件)

      b) 通过定义class as final 来停止继承

      间接回答问题

      c)停止重新发明*(如果您按照示例建议创建访问层) 并使用已经存在的PDO

      d) 使用一些合适的 OO 设计模式 e.g 并检查 this also 。 你的反应会是为什么?因为使用模式将解决许多继承和依赖问题,例如在访问层的情况下,子对象将不会被实例化,除非它不是用依赖对象创建的,例如在工厂案例中

      f) 成为public , private and protected keywords的用户

      【讨论】:

      • 你在打字的时候打败了我。 :)
      • 这不起作用,因为一旦加载了DBAccess.php,这个常量就被定义了,其他文件将能够调用DBAccess文件夹中的文件,因为这个常量已经定义了。不过,将类设置为 final 是停止继承的好方法。
      • 是的,你是对的,所以我说out of contextaccessing directly