简体   繁体   English

require_once不起作用,但require在php中起作用

[英]require_once not working but require does in php

I need to access a configuration variable from inside a method in a public class. 我需要从公共类的方法内部访问配置变量。 The file where the variable is stored is included into the ajax.php page where I also call the class constructor and his method 存储变量的文件包含在ajax.php页面中,在该页面中我还调用了类构造函数及其方法

<?php
    include_once('../config/config.php');
    [...]
    $myclass = new myclass();
    $res = $myclass->mymethod();
    echo json_encode($res);
?>

I tried to print the $config variable stored into config.php from inside the myclass method mymethod and it doesn't do anything. 我试图从myclass方法mymethod的内部打印存储在config.php中的$ config变量,它什么也没做。 If I try to call include_once('../config/config.php') it doesn't load anything and the $config varialbe is always empty, while if I try to include('../config/config.php') I can access the $config variable data without problem. 如果我尝试调用include_once('../ config / config.php')不会加载任何内容,并且$ config varialbe始终为空,而如果我尝试包含('../config/config.php' )我可以毫无问题地访问$ config变量数据。

So, if I understand correctly how include and include_once works, the _once just skip to import the file 'cause it has already been included before. 因此,如果我正确理解了include和include_once的工作原理,那么_once只是跳过导入文件,因为之前已经包含了它。 My question is, how can I access $config without being forced to include it again with include (not _once) ? 我的问题是,如何才能在不被迫再次包含include(而不是_once)的情况下访问$ config?

Your problem is understanding variable scope. 您的问题是了解变量范围。 You need a way to make your config array accessible to your class level methods. 您需要一种使配置数组可用于类级方法的方法。

The simplest method would be to pass a copy to the class in the constructor (or the individual method if it is only required in one): 最简单的方法是将副本传递给构造函数中的类(如果只需要一个,则将其传递给单个方法):

//config.php

$config=array(
    'something'=>'value',
    'somethingelse'=>10
);

//myclass.php    
class MyClass{
    private $config;

    public function __construct(array $config){

        $this->config = $config;
    }

    public function mymethod(){

        return $this->config['something'];
    }
}

//index.php 
include_once('../config/config.php');

$myclass = new MyClass($config);

echo $myclass->mymethod();//outputs 'value'

If this is purely readonly another option would be to wrap config array in a static class method: 如果这纯粹是只读的,则另一个选择是将配置数组包装在静态类方法中:

//config.php
class Config{
    public static function getConfig(){
    return array(
        'something'=>'value',
        'somethingelse'=>10
        );
    }
}

//index.php 
include_once('../config/config.php');

//anywhere in your code
$config = Config::getConfig();

echo $config['something'];

This initializes a new array every time its called so its not a great option. 每次调用它都会初始化一个新数组,因此不是一个好选择。

A third option would be to wrap your config in a singleton class, which is initialized only once but available via a static method call anywhere 第三种选择是将您的配置包装在单例类中,该类仅初始化一次,但可通过任何地方的静态方法调用使用

//config.php
class Config{
    public $config;
    private static $inst=null;

    private function __construct(){
        $this->config=array(
            'something'=>'value',
            'somethingelse'=>10
        );
    }

    public static function Instance(){
        if(static::$inst==null){
            static::$inst=new Config();
        }
        return static::$inst;
    }
}

//index.php 
include_once('../config/config.php');

//anywhere in your code

echo Config::Instance()->config['something'];

The singleton pattern is convenient, but has its (often debated well publicised) problems. 单例模式很方便,但是存在(经常辩论且广为宣传)的问题。

Ultimatly the 1st option is probably what you need. 最后,第一种选择可能是您需要的。

As a another way to do the same thing as was suggested before: 作为执行之前建议的另一种方法的另一种方式:

config.php config.php

<?php 
return array(
    'hostname' => 'localhost',
    'username' => 'dev',
    'passwrod' => '',
);

MyConfig.php MyConfig.php

<?php
class MyConfig extends ArrayObject
{
    public function __construct($filename)
    {
        parent::__construct();
        $this->setFlags(ArrayObject::ARRAY_AS_PROPS);

        if (!is_readable($filename)) {
            throw new InvalidArgumentException("Invalid file name: ".$filename);
        }
        $loaded_data = include($filename);

        foreach ($loaded_data as $index => $value) {
            $this->offsetSet($index,$value);
        }
    }
}

And then you can use like this MyClass.php 然后您可以像这样使用MyClass.php

class MyClass{
    private $config;

    public function __construct($config){
        $this->config = $config;
    }

    public function mymethod(){
        return $this->config->hostname .":". $this->config->username;
        // or even
        //return $this->config['hostname'] .":". $this->config['username'];
    }
}

the nice thing about MyConfig inheriting ArrayObject is that you can use the array values as properties. MyConfig继承ArrayObject的好处是可以将数组值用作属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM