So, let's drop PHP for a moment. If you were writing a database library in say Java, how would you know or prevent the user passing you a concatenated string over a string literal? Is it Java's fault that you can't (excepting major bytecode hackery maybe?)?
Education can go a long way. If you check the PHP PDO docs [0], the fact that prepared statements make SQL injection possible is only the second most important fact for them. The documentation for PDO::prepare does not mention this fact at all. It just says you can use placeholders. Great.
Or just use an ORM. They have a bad reputation, but SQLAlchemy + Python is an awesome combo. But because of language features, PHP ORMs aren't quite as seamless.
> If you were writing a database library in say Java, how would you know or prevent the user passing you a concatenated string over a string literal?
Extend the language to detect passing a string literal to certain functions or macros. Rust does this for macros that take a format string, like "println!" and "format!". GCC can do this for printf as well. And Perl has taint checking.