1

$layers関数内からアクセスする必要がありますisOk($layer)が、関数変数の外側で試したことはすべて$layers問題ありませんが、関数内では、グローバルであっても null が返されます。

コードは次のとおりです。

$layers = array();
foreach($pcb['PcbFile'] as $file){
    if(!empty($file['layer'])){
        $layers[$file['layer']] = 'ok';
    }
}
// Prints OK!
var_dump($layers);

function isOk($layer){
    global $layers;
// Not OK! prints NULL
    var_dump($layers);
    if(array_key_exists($layer, $layers))
        return ' ok';
    return '';
}
// NOT OK
echo isOk('MD');

私は常にオブジェクト指向を使用していますが、これは単純な関数で作成した非常に単純なものでした...$layers関数内で正しく「受信」されないのはなぜですか?

4

2 に答える 2

6

これを見て...

HalfAssedFramework.php

<?php
class HalfAssedFramework {
    public static function run($path) {
        include $path;
    }
}

HalfAssedFramework::run('example.php');

example.php

<?php

$layers = array();
foreach($pcb['PcbFile'] as $file){
    if(!empty($file['layer'])){
        $layers[$file['layer']] = 'ok';
    }
}
// Prints OK!
var_dump($layers);

function isOk($layer){
    global $layers;
// Not OK! prints NULL
    var_dump($layers);
    if(array_key_exists($layer, $layers))
        return ' ok';
    return '';
}
// NOT OK
echo isOk('MD');

example.php直接実行すると、動作するはずです。実行しますHalfAssedFramework.phpが、そうではありません。

問題は範囲です。example.phpが関数内に含まれている場合、その中のrunすべてのコードは関数のスコープを継承します。そのスコープで$layersは、既定ではグローバルではありません。

これを修正するには、いくつかのオプションがあります。

  • example.php直接実行されないことがわかっている場合global $layers;は、ファイルの先頭で言うことができます。ただし、スクリプトを直接実行した場合にこれが機能するかどうかはわかりません。
  • $layersどこでも交換$GLOBALS['layers']
  • $layersに引数として追加しますisOk
  • Geoffreyの提案に従って、このコードをクラス内に配置します。
于 2012-08-10T03:48:12.370 に答える
2

質問に正確に答えているわけではありませんが、グローバルを使用しないことを検討しましたか? グローバルはそれほどクールではありません。コードを読みにくく、理解しにくくし、その結果、保守が難しくなります。

そのようなものを考えてみましょう:

<?php

class LayerCollection
{
    private $layers;

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

    public static function fromPcbFile($data)
    {
        $layers = array();

        foreach ($data['PcbFile'] as $layer) {
            if (!empty($layer)) {
                $layers[$layer] = true;
            }
        }

        return new self($layers);
    }

    public function hasLayer($layer)
    {
        return array_key_exists($layer, $this->layers);
    }
}

$layers = LayerCollection::fromPcbFile($pcb);
var_dump($layers->hasLayer('MD'));

もっと良く見えませんか?LayerCollectionレイヤーを操作する方法がさらに必要な場合は、エンリッチに進むことができます。これは完璧ではありませんstill。静的メソッドが横たわっているからです (テストが難しくなるため、その作業にはファクトリの方が適しています) が、リファクタリングの良い出発点です。

グローバルが悪い理由の詳細: https://softwareengineering.stackexchange.com/questions/148108/why-is-global-state-so-evil

于 2012-08-10T03:38:56.190 に答える