PHP抽象类数组保护属性

PHP抽象类数组保护属性,php,arrays,oop,properties,abstract-class,Php,Arrays,Oop,Properties,Abstract Class,我对使用抽象类和OOP有点陌生,所以请耐心听我说。 我正试图列出员工和客户的列表,但在打印StoreList类中的对象数组时遇到了一些问题,因为它们都受到保护。 我要做的是将storeArray中的值打印到一个漂亮的列表中。 现在,它从抽象类中打印出GET中的所有内容,使数组过时。 我将在下面列出所有代码,但由于代码很长,我想在这里提问。 这是当我将数组转储到index.php或Storelistclass.php上时数组发出的结果 array (size=5) 0 => o

我对使用抽象类和OOP有点陌生,所以请耐心听我说。
我正试图列出员工和客户的列表,但在打印StoreList类中的对象数组时遇到了一些问题,因为它们都受到保护。
我要做的是将storeArray中的值打印到一个漂亮的列表中。
现在,它从抽象类中打印出GET中的所有内容,使数组过时。
我将在下面列出所有代码,但由于代码很长,我想在这里提问。
这是当我将数组转储到index.php或Storelistclass.php上时数组发出的结果

array (size=5)
  0 => 
    object(Employee)[1]
      protected 'userId' => string '1' (length=1)
      protected 'userFirstName' => string 'Joe' (length=3)
      protected 'userLastName' => string 'Longo' (length=5)
      protected 'userTitle' => string 'Employee' (length=8)
  1 => 
    object(Customer)[2]
      protected 'userId' => string '1' (length=1)
      protected 'userFirstName' => string 'Bruce' (length=5)
      protected 'userLastName' => string 'Stark' (length=5)
      protected 'userTitle' => string 'Customer' (length=8)
  2 => 
    object(Customer)[3]
      protected 'userId' => string '2' (length=1)
      protected 'userFirstName' => string 'Tony' (length=4)
      protected 'userLastName' => string 'Wayne' (length=5)
      protected 'userTitle' => string 'Customer' (length=8)
  3 => 
    object(Customer)[4]
      protected 'userId' => string '3' (length=1)
      protected 'userFirstName' => string 'Oliver' (length=6)
      protected 'userLastName' => string 'Wilson' (length=6)
      protected 'userTitle' => string 'Customer' (length=8)
  4 => 
    object(Customer)[5]
      protected 'userId' => string '4' (length=1)
      protected 'userFirstName' => string 'Slade' (length=5)
      protected 'userLastName' => string 'Queen' (length=5)
      protected 'userTitle' => string 'Customer' (length=8)
无论我尝试在阵列中运行foreach循环,都会出现以下错误: 无法访问受保护的属性

foreach($this->storeArray as $data)
{
    echo $data->userFirstName;
}
当我公开用户抽象类中的属性时,它工作得很好,但是GET会过时,对吗? 我是应该放弃GET并将其公开,还是有其他方法?
对不起,如果这是一个愚蠢的问题,但我真的试图把我的头围绕在这个问题上,但失败了

任何帮助和提示(也包括更新和删除功能)都将不胜感激

这是我现在所有的代码。

index.php:

<?php
include("classes/Userclass.php");
include("classes/Customerclass.php");
include("classes/Employeeclass.php");
include("classes/Storelistclass.php");

$employeeOne = new Employee("1","Joe","Longo","Employee");

$customerOne = new Customer("1","Bruce","Stark","Customer");
$customerTwo = new Customer("2","Tony","Wayne","Customer");
$customerThree = new Customer("3","Oliver","Wilson","Customer");
$customerFour = new Customer("4","Slade","Queen","Customer");

$list = new Storelist($employeeOne);
$list->addCustomer($customerOne);
$list->addCustomer($customerTwo);
$list->addCustomer($customerThree);
$list->addCustomer($customerFour);
?>

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <!--<link href="includes/stylesheet.css" rel="stylesheet" type="text/css"/>-->
    <title>Store List</title>
  </head>
  <body>

<h1>Test Get Customer</h1>
<p>
  <?php
    echo $customerOne->getUserTitle()." #". $customerOne->getUserId() ."'s First name is ". $customerOne->getUserFirstName() ." and Last name is ". $customerOne->getUserLastName() ."<br/>";
    echo $customerTwo->getUserTitle()." #". $customerTwo->getUserId() ."'s First name is ". $customerTwo->getUserFirstName() ." and Last name is ". $customerTwo->getUserLastName() ."<br/>";
  ?>
</p>

<h1>Test Get Employee</h1>
  <p>
  <?php 
    echo $employeeOne->getUserTitle()." #". $employeeOne->getUserId() ."'s First name is ". $employeeOne->getUserFirstName() ." and Last name is ". $employeeOne->getUserLastName() ."<br/>";
  ?>
</p>

  <h1>Storelist Foreach</h1>
    <p>
      <?php
      $listtest = $list->buildList();
      echo $listtest;
      ?>
  </p>
<?php

class Employee extends User
{
    public function userSayHi()
    {
        return 'Hello , how may i help u?';
    }   
}
Employeeclass.php:

<?php
include("classes/Userclass.php");
include("classes/Customerclass.php");
include("classes/Employeeclass.php");
include("classes/Storelistclass.php");

$employeeOne = new Employee("1","Joe","Longo","Employee");

$customerOne = new Customer("1","Bruce","Stark","Customer");
$customerTwo = new Customer("2","Tony","Wayne","Customer");
$customerThree = new Customer("3","Oliver","Wilson","Customer");
$customerFour = new Customer("4","Slade","Queen","Customer");

$list = new Storelist($employeeOne);
$list->addCustomer($customerOne);
$list->addCustomer($customerTwo);
$list->addCustomer($customerThree);
$list->addCustomer($customerFour);
?>

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <!--<link href="includes/stylesheet.css" rel="stylesheet" type="text/css"/>-->
    <title>Store List</title>
  </head>
  <body>

<h1>Test Get Customer</h1>
<p>
  <?php
    echo $customerOne->getUserTitle()." #". $customerOne->getUserId() ."'s First name is ". $customerOne->getUserFirstName() ." and Last name is ". $customerOne->getUserLastName() ."<br/>";
    echo $customerTwo->getUserTitle()." #". $customerTwo->getUserId() ."'s First name is ". $customerTwo->getUserFirstName() ." and Last name is ". $customerTwo->getUserLastName() ."<br/>";
  ?>
</p>

<h1>Test Get Employee</h1>
  <p>
  <?php 
    echo $employeeOne->getUserTitle()." #". $employeeOne->getUserId() ."'s First name is ". $employeeOne->getUserFirstName() ." and Last name is ". $employeeOne->getUserLastName() ."<br/>";
  ?>
</p>

  <h1>Storelist Foreach</h1>
    <p>
      <?php
      $listtest = $list->buildList();
      echo $listtest;
      ?>
  </p>
<?php

class Employee extends User
{
    public function userSayHi()
    {
        return 'Hello , how may i help u?';
    }   
}

解决方案是实际使用getter方法(
getuserwhatch()
),您在定义时遇到了麻烦。通过使用
protected
visibility使它们保持原样,除了使用您定义的
setuserwhather()
方法之外,不可能修改它们,因此您可以执行其他验证(例如,防止非空值)并对无效数据抛出异常。因此,它们不能像
public
属性那样从类外直接可变是很有用的

Storelist
类中,您已经定义了具有
public
可见性的
$storeArray
属性,这意味着您可以在
index.php
中的类外读取它。由于要将
员工
客户
对象添加到该数组中,因此这些对象仍然可以通过
$list->storeArray
上的数组键单独寻址。例如,要修改姓氏,可以使用

// Set the 3rd user's last name
$list->storeArray[2]->setUserLastName('Jones');
同样,在
Storelist
类中使用
$this
也可以实现这一点:

// Inside Storelist
$this->storeArray[2]->setUserLastName('Jones');
因此,您已经基本上了解了这些类的布局。还有一件事我可以建议;由于您已经创建了使用方法调用将
Customer
Employee
对象添加到
Storelist::$storeArray
的方法,而不是直接修改数组:

// You're doing this:
$list = new Storelist($employeeOne);
$list->addCustomer($customerOne);

// And not this (directly modifying storeArray):
$list = new Storelist($employeeOne);
$list->storeArray[] = $customerOne

……同时也考虑定义<代码> Stulelist::$StururRie<代码>作为<代码>受保护的属性,以便您只能用它的SETTER方法写入它。然后还需要创建一个返回数组的getter方法

class Storelist
{
    // This becomes protected
    protected $storeArray = [];

    // So you need a getter:
    public function getStoreArray()
    {
       return $this->storeArray;
    }
    // etc...
}
若要从
index.php
修改数组,则不能再直接读取其元素。而是将其称为getter方法:

// You can't do this:
$list->storeArray[2]->setUserLastName('Jones');

// Instead do it via the getter:
$list->getStoreArray()[2]->setUserLastName('Jones');

(注意,上面的
()[2]
语法需要PHP5.4+

Storelistclass.PHP
文件中,当前有两个版本的循环。注释掉的循环不起作用,但未注释的循环就可以了。通过它们的public
getuserwhicher()
方法调用这些属性正是您应该做的,而不是修改底层的
抽象用户
使它们成为public
属性。在
buildList()
中使用这些getter方法,您有什么不喜欢的地方吗?我不会让它们公开,而是让它们保持原样。你说“现在它从抽象类的GET中打印出所有内容,使数组过时”——我不确定你认为数组过时了什么。StoreList在内部保存客户和员工的列表;这似乎很好。@MichaelBerkowski谢谢你的回答,我的老师提到使用数组(虽然他没有说,但不确定是否用于打印),但是我不需要将数组用于Storelist类中现在为空的更新/删除函数吗?如果我无法从数组中访问属性以进行打印,我也将无法编辑/删除它们(我的思维过程)。您可以在
update()/delete()
方法中使用该数组-我假设
delete()
旨在从数组中删除用户。如果要修改用户属性,可以使用StoreList类中的
setUserWhather()
方法进行修改-不需要直接写入属性,因为setter会为您处理。所以,你现在拥有的一切在我看来都很好。@MichaelBerkowski嗯,好吧,但我该怎么做呢?因为我无法访问数组属性,所以我不知所措。也许我只是把自己弄糊涂了,呵呵。
// You can't do this:
$list->storeArray[2]->setUserLastName('Jones');

// Instead do it via the getter:
$list->getStoreArray()[2]->setUserLastName('Jones');