Ciao, potresti fare un cast ad object nel metodo __get. Mi spiego:
Codice PHP:
function __get($name){
      return (object)
$this->prova[$name];

In questo modo l'array associativo che ritorna __get nel tuo caso viene trasformato in un oggetto e quindi puoi chiamare $x->foo->a come dicevi tu. Il problema sorge nel momento in cui $this->prova[$name] non contiene un array associativo, quindi...da usare con cautela