如何在不传递数组的情况下将数组访问到类中?

时间:2017-07-22 10:21:30

标签: php arrays scope global-variables

我有一个.ini文件作为我项目的配置。现在我想让它随处可见。 Here简化了我尝试做的事情:

<?php

$config = [];
$config['base_url'] = '/mypath/';

class myclass{

    public function myfunc(){
        print_r($config);
    }
}

$obj = new myclass;
$obj->myfunc;

正如你在小提琴中看到的那样,它会抛出:

  

注意:第14行的未定义属性:myclass :: $ myfunc in / in / iNZOv

注意到当我使用global关键字时,它会抛出语法错误

看,我可以像这样将数组传递给类:

$obj = new myclass($config);

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

但我不能每次都为所有课程都这样做。无论如何,我想知道,是否有可能在全球范围内访问数组?

6 个答案:

答案 0 :(得分:1)

使用var sb = new StringBuilder(); sb.AppendLine("sep=,"); sb.AppendLine("COL1,COL2,COL3,...,COL-N"); // columns using (IDataReader reader = dbInstance.ExecuteReader(dbCommand)) { DataRow newRow; while (reader.Read()) { sb.Append((string)reader["COL1"] + ","); sb.Append((string)reader["COL2"] + ","); sb.Append((string)reader["COL3"] + ","); ... sb.Append((string)reader["COL-N"] + Environment.NewLine); } } return sb.ToString(); // returns string representing CSV file content 。您还需要<policy-violations><policy-violation> <id>266</id> <name>CPU utilization is too high</name> <startTimeInMillis>1452630655000</startTimeInMillis> <detectedTimeInMillis>0</detectedTimeInMillis> <endTimeInMillis>1452630715000</endTimeInMillis> <incidentStatus>RESOLVED</incidentStatus> **<severity>WARNING</severity>** <triggeredEntityDefinition> <entityType>POLICY</entityType> <entityId>30</entityId> <name>CPU utilization is too high</name> </triggeredEntityDefinition> .... 而不是global,因为它是成员函数

$obj->myfunc();

答案 1 :(得分:1)

numthreads是一种方法,而不是属性。因此myfunc应为$obj->myfunc;

虽然不推荐,但您可以使用$obj->myfunc();访问功能中的global

config

以下是对why Globals are evil的好读。

答案 2 :(得分:1)

在函数外部定义变量时,它已经在全局范围内。

您也可以通过“超级全球”$_GLOBAL["variable_name"]访问它们;

但问题是您正在将方法称为属性。

答案 3 :(得分:1)

不要依赖全局变量。决不。在一个完美的世界里,你需要的是为你的班级写一个合适的factory。不需要在需要时随处输入$obj = new MyClass();,而是拥有一个工厂并创建MyClass实例,这样就有了更好的方法。

基本上你的问题是进入依赖注入主题。一个简单的数组或对象,它并不重要。您的MyClass在此处具有依赖关系,并且此依赖关系可能在将来发生更改。此问题是依赖注入容器的发明背后的基本原因。

我有机会PimpleAura DI熟悉容器。

以下是Pimple的一个示例(假设您的项目使用了composer)。转到项目根目录并获得粉刺:

 $ composer require pimple/pimple ~3.0

在应用的早期步骤中创建和配置容器:

use Pimple\Container;

$dic = new Container();
$dic['config'] = function ($c) {
    return ['base_url' => '/mypath/'];
};

$dic['myclass'] = function ($c) {
    return new MyClass($c['config']);
};

现在,您只需输入以下内容即可在应用程序的任何位置获取课程:

$obj = $dic['myclass']; // $obj is a new, shiny MyClass instance here

您的MyClass签名应如下所示:

private $config; // Always start with reduced visibility

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

public function myfunc() {
    print_r($this->config);
}

答案 4 :(得分:0)

最佳解决方案是使用这样的用户定义函数:

<?php

function config( $key = null ){

    // $config = parse_ini_file('../out_of_root/app.ini');
    $config = [];
    $config['base_url'] = '/mypath/';

    if ( is_null($key) ){
        return $config;
    } else if ( array_key_exists($key, $config) ) {
        return $config[$key];
    } else {
        return "key doesn't exist";
    }
}

class myclass{

    public function myfunc(){
        echo config('base_url');
    }
}

$obj = new myclass;
$obj->myfunc();

Demo

答案 5 :(得分:0)

我也不建议使用global。容器一般都很好,但有时它太多了。这是一个带有静态变量和方法的简单解决方案。

class Config
{
    public static $values = [
        'base_url' => '/mypath/'
    ];

    /**
     * @param string $key
     * @return null|string|int|mixed
     */
    public static function get($key)
    {
        return empty(self::$values[$key]) ? null : self::$values[$key]; // alternatively you can throw an exception for a missing key.
    }
}

class Foo
{
    public function printConfig()
    {
        print_r(Config::$values);
    }
}

(new Foo)->printConfig();
echo Config::get('base_url');