PHP:在OOP中追加对象?

I've transitioned my coding step by step into OOP, which feels great. What I haven't got a hold of yet, is when It's time to use an object and when to use the conventional arrays.

Let's say that I would have the following code. Here we create an array containing Persons - receivers of emails. It's really cute, but it feels kind of smelly to jump back and forwards between arrays and objects.

Are my concerns legitimate or is this good practice?

public function receiver($email, $name = FALSE) {

    $person = new Person();
    $person->email = $email;
    $person->name = $name;

    $this->receiver[] = $person;
}

That's absolutely fine, OOP doesn't preclude using arrays where appropriate.

In fact, arrays are often found hiding in OOP objects. The goal of classes/objects is to describe the properties of something. If that something needs to store multiple values of the same type, then there totally could be an array in there.

For instance, a class describing a Car/Automobile, might have an array that stores Seats.

There is nothing wrong with arrays, and if you have that idea then it is possible that you can "over-objectify" your code. Some things just don't make sense to create an object for.

In your example, it looks like your object has a property called receiver, as well as a method called receiver. That isn't the best of practices... keep your method and property names distinct.

As for arrays and objects and whatnot, look in to the Iterator (click for docs) interface. This allows you to treat an object like an array in foreach loops and the like.

To answer your exact question, yes, using arrays is fine. You could use something like SplObjectStorage instead, but for most use-cases, an array is quite fine...

I would do this differently. Instead of creating the object inside the method, I'd pass the object in:

public function receiver(Person $person) {
    $this->receiver[] = $person;
}

Then calling with:

$person = new Person();
$person->email = 'email@example.com';
$obj->receiver($person);

That way, you're decoupling the implementation of the Person object from the current object (whetever it is). Even better would be to declare an interface depending on how you expect it to work for that usage, and require an implementation of that interface:

interface iEmailable {
    public function getName();
    public function getEmail();
}
class Person implements iEmailable {
    protected $name = '';
    protected $email = '';
    public function __construct($name, $email) {
        $this->name = $name;
        $this->email = $email;
    }
    public function getName() {
        return $this->name;
    }
    public function getEmail() {
        return $this->email;
    }
}

then, adjust your method to:

public function receiver(iEmailable $person) {
    $this->receiver[] = $person;
}

Now, you're much more decoupled from the concrete Person class. Any class is free to be passed in, as long as it implements the proper interface...