First, StackOverflow is a great place to take advice, as every user is reviewed and there are so many good eggs there, bad or out-dated advice is pointed out right away, and best practices almost always end up as the top answer.
Second, PHP.net is an official resource for learning PHP, so is a great place to learn as well.
Thirdly.. A "project which may involve a high amount of logic usage and would be challenging to complete" is hard to come up with without knowing your level of skill, or what it is you're trying to learn..
One of my favorite things to do in PHP is to use the
You must be registered to see links
to make a given part of the PHP API easier to use. In the case of PHP, this use-case (quoted from Wikipedia) best describes my reasoning:
For example, you could make a MySQL class which makes the MySQLi API or the MySQL specific parts of the PDO API easier to work with.
When constructing an API using the Facade Pattern, I like to design the implementation before any of the API parts. For example, I make a hypothetical implementation like this:
PHP:
$db = new \Database\MySQL($host, $username, $password);
$userData = $db->select('*')->
from('users')->
where(['username'=>'foo', 'password'=>'bar']);
var_dump($userData);
/*
[
'id' => 134,
'username' => 'foo',
'password' => *some hash string*
'email' => 'foo@example.com'
... all other data stored in the users table for the username 'foo' ...
]
*/
Now with that done, I would build the API so that the above implementation would actually work.
Edit: Sometimes my hypothetical implementation is not quite right. The above example expects a 1-dimensional associative array as the result. That's not actually ideal for MySQL. Most of the time the result is a numeric array (rows) of a 1-dimensional associative array. So, after realizing that, I would update the hypothetical implmenetation to be more realistic:
PHP:
var_dump($userData);
/*
[[
'id' => 134,
'username' => 'foo',
'password' => *some hash string*
'email' => 'foo@example.com'
... all other data stored in the users table for the username 'foo' ...
]]
*/
With that said, it's okay to deviate from the hypothetical implementation a little bit, but for the most part, try to religiously fight to make the hypothetical implementation work as-is.