0

現在、メンバー関数にアクセスできる関数を作成しようとしています。問題のコードは次のようになります。

protected $formName;
protected $formClass;
protected $formAction;
protected $formMethod;
protected $formObjArray = array(); //outputs in order. So far it should only take newLine, selectTag, inputTag, textTag.
protected $submitBtnVal;
protected $encType;

function __construct($args) {
  $this->formName = $args['formName'];
  $this->formAction = $args['formAction'];

  if (isset($args['formClass'])) $this->formClass = $args['formClass'];
  if (isset($args['encType'])) $this->encType = $args['encType'];

  //default should be POST. Hell, you should never really be using GET for this..
  //also, the default submit value is Submit
  $this->formMethod = isset($args['formMethod']) ? $args['formMethod'] : "POST"; 
  $this->submitBtnVal = isset($args['submitBtnVal']) ? $args['submitBtnVal'] : "Submit";
}

//get functions
function getFormName () { return $this->formName; }
function getFormAction () { return $this->formAction; }
function getFormMethod () { return $this->formMethod; }
function getSubmitBtnVal () { return $this->submitBtnVal; }
function getEncType () { return $this->encType; }

//set functions
function setFormName ($newName) { $this->fromName = $newName; }
function setFormAction ($newAction) { $this->formAction = $newAction; }
function setFormMethod ($newMethod) { $this->formMethod = $newMethod; }
function setEncType ($newEType) { $this->encType = $newEType; }

function addTag($newTag) {
  if ($newTag instanceof formTag || $newTag instanceof fieldSetCont || $newTag instanceof newLine
      || $newTag instanceof noteTag)
    $this->formObjArray[] = $newTag;
  else throw new Exception ("You did not add a compatible tag.");
}

通話できるようにしたい$myForm->getTagByName("nameA")->setRequired(true);

どうすればいいですか?それとも、もっと何かをする必要がありますか..

$tagID = $myForm->getTagByName("nameA");
$myForm->tagArray(tagID)->setRequired(true);
4

2 に答える 2

2

あなたのコードには何も保護されていないように見えるので、アクセスに問題はありません。

すべてのタグが $formObjArray にあるように見えるので、配列よりもフィルタリングして、渡した名前に一致するタグを返すのは簡単なはずgetTagByNameですgetTagsByName。同じ名前のタグを複数持つことができます。配列を返すため、戻り値を呼び出すことはできませんsetRequired。配列にはそのようなメソッドがありません。次のようにする必要があります。

$tags = $myForm->getTagsByName("nameA");
foreach ($tags as $tag) {
    $tag->setRequired(true);
}

正確に何にこだわっていますか?質問の意味がよくわからないかもしれません。

たぶん、フィルタリングが行き詰まっていますか?これを試してください(少なくともphp 5.3を使用している場合)

function getTagsByName($tagname) 
{
    return array_filter($this->formObjArray, function($tag) use($tagname) { 
        return $tag->getName() == $tagname; 
    });
}

ifs やスイッチはありません。

5.3 より前では、ラムダ関数がないため、別の方法で行う必要があります。いくつかのオプションがありますが、これが最も理解しやすいかもしれません。

function getTagsByName($tagname) 
{
    $out = array();
    foreach ($this->formObjArray as &$tag) {
        if ($tag->getName() == $tagname) {
            $out[] = $tag;
        }
    }
    return $out;
}
于 2012-05-28T01:31:55.703 に答える
1

addTag メソッドでは、[] 表記を使用して $this->formObjArray に新しいタグを格納しています。これは、新しいタグを配列の最後に追加するだけです。すべてのタグ オブジェクトに getName() メソッドがある場合は、次のようにすることができます。

$this->formObjArray[$newTag->getName()] = $newTag;

次に、 getTagByName() メソッドを簡単に追加できます。

public function getTagByName($name) {
  if (array_key_exists($name, $this->formObjArray) {
    return $this->formObjArray($name);
  }
  else {
    return null;
  }
}

配列内のすべてのタグを反復処理することを提案するソリューションに注意してください! フォームが大きくなると、これは非常にコストがかかる可能性があります。

追加された要素の順序が重要なために [] 構造を使用する必要がある場合でも、別のインデックス $this->tagIndex を名前で維持できます。これは name => tag の連想配列になります。オブジェクト参照を保存しているので、それらは多くのスペースを使用しません。getTagByName が何度も使用されると仮定すると、これにより、getTagByName を呼び出すたびにタグ配列を反復するよりも多くのリソースを節約できます。

その場合、addTag メソッドは次のようになります。

$this->formObjArray[] = $newTag;
$this->tagIndex[$newTag->getName()] = $newTag; // it seems that you're doubling the memory needed, but you're only storing object references so this is safe

編集:複数のタグが同じ名前を持つことができるという事実を説明するために、いくつかの変更されたコードを次に示します。

addTag() メソッドで、次のようにします。

$this->formObjArray[] = $newTag;
$tag_name = $newTag->getName();
if (!array_key_exists($tag_name, $this->tagIndex)) {
  $this->tagIndex[$tag_name] = array();
}
$this->tagIndex[$tag_name][] = $newTag

その後、getTagByName の名前を getTagsByName に変更して、期待どおりの結果を得ることができます。

コメントで述べたように、これは getTagsByName を複数回呼び出す場合にのみ役立ちます。名前によるルックアップを高速化するために、少し追加のメモリ使用量をトレードしています。

于 2012-05-28T02:18:28.530 に答える