Basically, I agree with your statements, but I would go a bit deeper.
The controller is your mediator between the View and your Model. So as you said, the View is unaware of the controller, but so is the Model.
Also, in your model, as you mentioned, that's also a good point to have the Service layer as en entry point of your model !
You always have to keep in minde that the Controller and View layers might be on a server, and the model on an other one. So your service acts as a facade between your business need and your business logic. It also may handle your transactions, error standardisation, etc... Transverse things actually.
For your domain part, I would extend your mapper part by dividing it into 2 distinct parts. Since it's your DAL, you may want to create class for :
- Requesting your domain objects, wherever they come from
- Retrieving your domain objects, from a specific location
I mean, your BL requests your DAL an object, so you ask your storage to give it to you. The storage has a set of retrievers, such as a level1 cache (regular php array), level2 cache (memcached, redis, anything), and finally your database. So I'd basically have 2 sub layers in the DAL : a storage class with its stack of stores and priorities, and an implementation for the fetch in those stores.
Don't forget to step into your layers only using factories, so that it will be easier to make unit testing by mocking your objects inside them, or add interceptors between each layer.