PHP доступ к значениям массива и ключи внутри цикла - PullRequest
0 голосов
/ 26 июля 2011

Я новичок в 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/>';
    }   

Вот класс Напитка:

<?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 ]

3 голосов
/ 26 июля 2011
$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 голос
/ 26 июля 2011

В дополнение к использованию foreach, как показывает Мэтт, Drink может реализовывать интерфейсы Iterator или IteratorAggregate, так что вы можете перебирать напитки напрямую, скорее чем необходимость создания второго массива. Это может быть так же просто, как использовать 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";
        }
    }
}

Свойство перегрузка (__get, __set) не требуется для итерации, но допускает доступ на запись в цикле foreach с использованием имен свойств переменных (например, $drink->$name). Имена свойств переменных следует использовать с осторожностью, поскольку они могут скрыть, к какому свойству обращаются, но это приемлемо в цикле foreach, поскольку ясно, что к каждому доступному свойству обращаются.

Вы можете переместить валидацию в методы set*, создавая исключения при сбое, после чего не будет необходимости в шаге валидации.

Примечания:
не семантические . Часто его следует заменить элементами абзаца (

) и т. П., Используя стилизацию для создания пространства. Шаблоны должны быть привязаны в начале (^) и конце ($), в противном случае вы можете получить успешное совпадение только для части значения, что приведет к успешному выполнению проверки в случае сбоя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...