ORM doesn't save you from understanding how code works. It is not a tool to avoid learning SQL or UnitOfWork pattern.
But it has other advantages: you can use objects for your models, you can use lazy loading and relations between models, you don't have to save modified entities explicitly. So it helps to avoid writing low level code for saving and loading data from a database. You don't have to write routine methods like "get something by id", "get tags for post" or "update a field in a table".
> it encourages the promiscuous mingling of code and behavior, and makes it very difficult to produce code which can be understood without reference to complex interactions among many instances of many classes.
That might be over-engineering. OOP doesn't require you to use every single pattern from a book or build multilevel hierarchies of abstract classes. Abstract classes and interfaces might be necessary when you try to build reusable libraries or components but you don't have to use them inside a monolith application.
But you need to learn things like single responsibility principle so you can divide complex tasks into smaller parts. You have to remember that your code will be maintained by other people so it needs to be easy to understand without searching through all the codebase and hard to break.
And whatever approach you use when you have an application with large codebase written by many people it will be complicated anyway. OOP can help you to organize this code.
> ORM in a typed language
PHP is not statically typed language but you can use type hints for functions. So if you have an argument with a class name specified you can quickly look up what properties and methods the object has (and your IDE will suggest autocomplete options). And you cannot have any such information if the argument is an array.
I used to work with large applications written using "SQL and arrays" approach and they were bad. I had to spend most time figuring out what kind of array is passed to some function and how it is used to display something on a page. And it is hard to check if you don't break something by removing or changing a single element in that array. That is why I think this approach is not scalable beyond small applications written by a single developer. It has no relation to whether mixed arrays are allowed in a language or not. You can get same kind of code if you misuse collections in Java or C# or maybe Go.
You can look at Drupal if you need an example of complex open source application with those problems. It passes a lot of arrays around that are not even documented anywhere. And as an example of OOP application you can see Magento. It is large and very customizable so they had to use different abstractions.