我是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"];
}
}
?>
答案 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
可以实现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";
}
}
}
属性overloading(__ get,__ set)对于迭代不是必需的,但允许使用变量属性名称(例如foreach
)在$drink->$name
循环内进行写访问。应谨慎使用变量属性名称,因为它们可以混淆正在访问的属性,但它在foreach循环中是可接受的,因为很明显正在访问每个可访问的属性。
您可以将验证移至set*
方法,在失败时抛出异常,此时不需要验证步骤。
注意:<br/>不是semantic。通常,它应该用段落(&lt; p&gt;)元素等替换,使用样式来创建空间。模式应该锚定在开始(^
)和结束($
),否则你只能在一部分值上获得成功匹配,从而导致验证失败时成功。< / p>