There WAS a lot of debate a number of years ago about password_hash and the bad practice of pulling the password -- even hashed -- from the database to be checked instead of keeping all password access mono-directional. Those who opposed it were shouted down and kicked out of contributing to PHP's future.
I still maintain that pulling the hash from the database is just plain stupid. Hence my approach remains to use the hash() command with something like sha256 if speed is a concern, sha512 or whirlpool if I want the best of the best of the best. You want to test for login, you hash the pass and test for equality in the query.
I also dislike how password_hash plays loosy-goosy mix and match of password formats, defeating any point of "hey don't use that algo anymore" that it ALLEGEDLY brings to the table. That a new algo isn't blanket applied or warnings aren't thrown to say to do so means you're still stuck manually changing algo's, at which point why bother with these functions in the first place?
Also when it comes to the database connection (PDO) is it best to keep that secured within a function? and not just generally connect and pass it around via a variable such as $DB?
Uhm, those are the same thing in terms of good practice -- you connect to it locally, then you pass $db only to FUNCTIONS that require its use. This is part of why library files should contain functions and NOT directly execute code.
(Something I wish they'd drop from being a thing in PHP altogether is that includes are in scope and directly execute code!)Hence my programs usually have a "main" function in their "one index to rule them all"
function main() does the following:
$db = connect to database
test for / log in user, passing $db to user object
load settings from passing $db to settings singleton
include the template
determine the user request type
include request handler, passing $db to request handler object/singleton
// do not pass $db past this point. Various PDOStatements would hold the results
template_header();
run request handler output function/object method which in turn calls its template
template_footer();
die(); // prevent further code execution, makes code appendages on index be dead code.
Then I run main() right after it is created.
This gives me granular control over what has access to the database and what does not, and since I write single index.php to handle all requests it gives me a single entry vector. Even if accidentally included/requried or run directly, NONE of my other library files can give away or do anything nasty as all they contain are functions and objects.
To me that's good practice. To folks who like things like turdpress that's "too hard" or "too restrictive" or "too smart" for them; what with their putting the security information for the database connection into DEFINE; super-global scope where they cannot be deleted, and hence 100% herpafreakingderp. I've seen so many PHP tutorials even advocating that approach and it's like "what the **** is wrong with you people?!?"
One of the BIGGEST security flaws in PHP architecturally is how includes are blindly just read in and run, meaning the language has no proper library model. Includes are automatically in scope to where they are called, they will just run the code included with zero concern for security be they included or called directly, it's a sloppy implementation at best.
Hence I even use this derpy routine:
function safeInclude($file) { include($file); }
For including libraries JUST so I can break scope -- the scope of the include becomes safeInclude instead.
Because the fact I can do this:
<?php
// test.php
$test = 'stupid';
include('stupid.php');
<?php
// stupid.php
echo $test;
... and it will work? That's "scope bleed" and it's absofragginglutely dumbass.
But again, my bread and butter for a decade was programming Ada for the fed. It gives me a very different outlook on what's secure and what's not.
Hence my own laundry list for "fixing" PHP's security woes?
1) remove all PHP shorttags. If it's .php it contains PHP code. No more of this willy-nilly <?php ?> rubbish or letting markup be interspersed without a direct echo command.
2) library files included or required can/should only contain functions or objects. No more "blind output" from an include.
3) stop allowing file functions like file_get_contents, readfile, fopen, and so forth to read or write to PHP includes / library files.
4) ditch double-quoted string support as well as confusing trash like heredoc/nowdoc. Not only are they less efficient, they're harder to read and often seem to cause either variables for nothing if proper escaping (htmlspecialchars for example) is done, or making people not even bother escaping opening up security holes.
But when I proposed these fixes over a decade ago, I got yelled at. THEN people wonder why I have an attitude about this ****!