The problem with public properties in PHP is its datatype weakness. Some languages you can get away with public so long as it has non-strict business rules to apply. In something like Java, you can say I need an integer, but it doesn't matter what it is. By default I will give you zero, but you can change it if you see fit:
public class MyClass
public int mynumber;
At least Java can guarantee to me that it is indeed an integer. Personally, I wouldn't do that in Java since it doesn't use properties with the get/set blocks, so this is more useful in a language like C# which chains the get/set mechanism directly to the derference: myobj.property = 4; would call the actual method that handles it. This behaviour can be simulated with PHP's __set method, but requires a large block in order to deal with case conditions. I'd still write each method separately and then chain it to the __set's variable name. I'd use reflection myself since I'm lazy and would only want to write the __set once and let it find and invoke the actual setProperty() method I've written. Problem there now becomes the use of by-reference primitives which do not pass through on the __set magic method.
PHP provides no integrity at the variable level. Because of this I can guarantee nothing from the storage of public variables:
public function __construct(Animal $pet)
$this->myPet = $pet;
public function getMyPetName()
$p = new MyPet(new Cat("KittyCat"));
// that above is fine. But since myPet property is public:
$p->myPet = "KittyCat";
// fatal error.
So in PHP, you need to use the setter mechanisms either by individual functions (what I'd recommend), or by simulating properties with private variables and chained set methods in order to ensure the datatypes. Objects in particular are the biggest problem to work with; I want to guarantee that an object has its integrity in place when dereferencing it. I can do that with setters during runtime.