php访问循环中的数组值和键

时间:2011-07-26 17:35:21

标签: php arrays key

我是php的新手,并已用其他语言编程。我试图解决某种编程情况:基本上我需要访问存储在对象中的字符串。对象的内部数据结构是关联数组。值是我试图访问的字符串。

这是我使用的代码:

<?php

class OrderAuthenticator
{
    private $OrderObj;


     public function __construct($Order)
    {
         echo 'Contructed an instance of Order Authenticator<br/>';
        $this->OrderObj = $Order;
        echo 'Instantiated OrderContainer<br/>';
    }


public function authenticate_Drinks()
    {
        //echo __LINE__ ;
//4 number or characters including spaces between them
        $pattern_drinkName = '([0-9a-zA-Z\s]{1,75})';
//100 characters with spaces allowed between them
        $pattern_drinkCalories = '([0-9]{0,3})';
//100 characters with spaces allowed between them
        $pattern_drinkCategory = '([0-9A-Za-z\s]{1,50})';
//100 characters with spaces allowed between them
        $pattern_drinkDescription = '([0-9A-Za-z\s]{0,300})';
        $pattern_drinkPrice = '([0-9.]{1,6})';
//echo __LINE__ ;
        $DrinkContainer = $this->OrderObj->getDrinkContainer();
//echo __LINE__ ;
        foreach($DrinkContainer as $Drink)
        {
            //print_r($Drink);
            echo __LINE__ ;
            echo '<br/>';

         }

}
?>

此代码生成以下输出:

Array ( 
    [0] => Drink Object ( 
        [dataArray:private] => Array ( 
            [drink_name] => SimpleXMLElement Object ( [0] => Gin ) 
            [drink_cals] => SimpleXMLElement Object ( ) 
            [drink_Category] => SimpleXMLElement Object ( [0] => Alocholic ) 
            [drink_desc] => SimpleXMLElement Object ( ) 
            [drink_price] => SimpleXMLElement Object ( [0] => 4.00 ) 
        ) 
    ) 
) 

现在,我需要做的是取出字符串值,我需要对每个值运行正则表达式检查。所以我需要将这些字符串中的每一个存储在某个循环中的变量中。

我有这个代码试图在上面的循环中做到这一点,但它没有工作:

$drink_name = $Drink->getName();
echo 'drink name = '.$drink_name.'<br/>';
$drink_calories = $Drink->getCalories();
echo 'drink calories = '.$drink_calories.'<br/>';
$drink_category = $Drink->getCategory();
echo 'drink category = '.$drink_category.'<br/>';
$drink_Description = $Drink->getDescription();
echo 'drink Description = '.$drink_Description.'<br/>';
$Drink_Price = $Drink->getPrice();
echo 'drink Price = '.$Drink_Price.'<br/>';

    if(!preg_match($pattern_drinkName, $drink_name))
    {
        echo __LINE__ ;
        return 'Drink name'.$drink_name .' did not match<br/>';
    }
    else if(!preg_match($pattern_drinkCalories, $drink_calories))
    {
        echo __LINE__ ;
        return 'Drink calories'.$drink_calories .' did not match<br/>';
    }
    else if(!preg_match($pattern_drinkCategory, $drink_category))
    {
        echo __LINE__ ;
        return 'Drink category'.$drink_category .' did not match<br/>';
    }
    else if(!preg_match($pattern_drinkDescription, $drink_Description))
    {
        echo __LINE__ ;
        return 'Drink Description'.$drink_Description .' did not match<br/>';
    }
    else if(!preg_match($pattern_drinkPrice, $Drink_Price))
    {
        echo __LINE__ ;
        return 'Drink Price'.$Drink_Price .' did not match<br/>';
    }
    else 
    {
        echo __LINE__ ;
        return 'Merchant Location input is valid<br/>';
    }   

这是Drink类:

<?php
class Drink
{

    private $dataArray;// = array();


    public function __construct()
    {
        echo 'Entered constructor for Drink.php<br/>';
        $this->dataArray = array();
    }

    public function setName($drink_Name)
    {
        echo 'Added Drink Name to DrinkObj= '.$drink_Name. '<br/>';
        $this->dataArray["drink_name"] = $drink_Name;
    }
    public function getName()
    {
        echo 'Inside Drink name<br/>';
        return $this->dataArray["drink_name"];
    }

    public function setCalories($drink_Cals)
    {
        echo 'Added Drink Calories to DrinkObj= '.$drink_Cals. '<br/>';
        $this->dataArray["drink_cals"] = $drink_Cals;
    }
    public function getCalories()
    {
        return $this->dataArray["drink_cals"];
    }

    public function setCategory($drink_Category)
    {
        echo 'Added Drink Category to DrinkObj= '.$drink_Category. '<br/>';
        $this->dataArray["drink_Category"] = $drink_Category;
    }
    public function getCategory()
    {
        return $this->dataArray["drink_Category"];
    }

    public function setDescription($drink_Desc)
    {
        echo 'Added Drink Description to DrinkObj= '.$drink_Desc. '<br/>';
        $this->dataArray["drink_desc"] = $drink_Desc;
    }
    public function getDescription()
    {
        return $this->dataArray["drink_desc"];
    }

    public function setPrice($drink_Price)
    {
        echo 'Added Drink Price to DrinkObj= '.$drink_Price. '<br/>';
        $this->dataArray["drink_price"] = $drink_Price;
    }
    public function getPrice()
    {
        return $this->dataArray["drink_price"];
    }  
}
?>

2 个答案:

答案 0 :(得分:3)

$patterns = array(
    'name' => '([0-9a-zA-Z\s]{1,75})',
    'calories' => '([0-9]{0,3})',
    'category' => '([0-9A-Za-z\s]{1,50})',
    'description' => '([0-9A-Za-z\s]{0,300})',
    'price' => '([0-9.]{1,6})'
);

$DrinkContainer = $this->OrderObj->getDrinkContainer();

foreach($DrinkContainer as $Drinks)
{
    foreach($Drinks as $DrinkObject)
    {
        $properties = array(
            'name' => $DrinkObject->getName(),
            'calories' => $DrinkObject->getCalories(),
            'category' => $DrinkObject->getCategory(),
            'description' => $DrinkObject->getDescription(),
            'price' => $DrinkObject->getPrice()
        );

        foreach($properties as $propname => $propvalue)
        {
            if(!preg_match($patterns[$propname], $propvalue))
            {
                return "Drink $propname $propvalue did not match<br/>";
            }
        }
    }
}

答案 1 :(得分:1)

除了使用foreach之外,正如Matt所示,Drink可以实现IteratorIteratorAggregate接口,因此您可以直接迭代饮品,而不必创建第二个数组。它可以像使用ArrayIterator来包装数据数组一样简单:

<?php
class Drink implements IteratorAggregate {

    function getIterator() {
        return new ArrayIterator($this->dataArray);
    }

    #...

或者您可以写一个课程:

<?php

class DataIterator implements Iterator {
    protected $data, $idx, $key, $fields;
    function __construct($data, $fields = null) {
        $this->data = $data;
        if ($fields) {
            $this->fields = $fields;
        } else if (method_exists($data, 'fields')) {
            $this->fields = $data->fields();
        } else {
            throw new InvalidArgumentException(__CLASS__ . ' expects ' . get_class($data) . " to have a 'fields' method, but it doesn't.");
        }
    }

    /*** Iterator ***/
    function current() {
        return $this->data->{$this->key};
    }

    function key() {
        return $this->key;
    }

    function next() {
        if (++$this->idx < count($this->fields)) {
            $this->key = $this->fields[$this->idx];
        } else {
            $this->key = null;
        }
    }

    function rewind() {
        $this->key = $this->fields[$this->idx = 0];
    }

    function valid() {
        return ! is_null($this->key);
    }
}

class Drink implements IteratorAggregate {
    private $dataArray = array(
        'drink_name' => null, 'drink_cals' => null, 
        'drink_Category' => null, 'drink_desc' => null,
        'drink_price' => null
        );

    function __get($name) {
        $method = 'get' . ucfirst($name);
        if (method_exists($this, $method)) {
            return $this->$method();
        }
        # else return value is undefined. Could also throw an exception.
    }

    function __set($name, $val) {
        $method = 'set' . ucfirst($name);
        if (method_exists($this, $method)) {
            return $this->$method($val);
        }
        # could throw and exception if $name isn't an accessible property.
    }

    /* Helps to describe Drinks by returning an array of property names.
     */
    function fields() {
        return array_keys($this->dataArray);
    }

    function getIterator() {
        return new DataIterator($this);
    }

    # ...
}

#...
$patterns = array(
    'name' => '(^[0-9a-zA-Z\s]{1,75}$)',
    'calories' => '(^[0-9]{0,3}$)',
    'category' => '(^[0-9A-Za-z\s]{1,50}$)',
    'description' => '(^[0-9A-Za-z\s]{0,300}$)',
    'price' => '(^[0-9.]{1,6}$)'
);
foreach($drinks as $i => $drink) {
    foreach($drink as $propname => $propvalue) {
        if(!preg_match($patterns[$propname], $propvalue)) {
            return "Drink $i's $propname ('$propvalue') is invalid.";
            # or:
            //$errors[$i][$propname] = "'$propvalue' is invalid";
        }
    }
}

属性overloading(__ get,__ set)对于迭代不是必需的,但允许使用变量属性名称(例如foreach)在$drink->$name循环内进行写访问。应谨慎使用变量属性名称,因为它们可以混淆正在访问的属性,但它在foreach循环中是可接受的,因为很明显正在访问每个可访问的属性。

您可以将验证移至set*方法,在失败时抛出异常,此时不需要验证步骤。

注意:<br/>不是semantic。通常,它应该用段落(&lt; p&gt;)元素等替换,使用样式来创建空间。模式应该锚定在开始(^)和结束($),否则你只能在一部分值上获得成功匹配,从而导致验证失败时成功。< / p>