I don't think you're interpreting me quite right

.
I wasn't referring to basename() being insecure in and of itself - merely that using it in isolation without supporting measures does in some circumstances lead to vulnerabilities. It's more a comment on the level of faith some developers put in native PHP functions, or rather their misinterpretation of those functions. basename() doesn't return a filename, it returns a string that passes for a valid system filename. That's a subtle distinction. Unfortunately some developers don't get the distinction and assume the returned string is what they consider a "safe filename", i.e. something which requires no other validation. This line of thinking drives a whole range of XSS and other attacks where filename fragments are displayed to users, admins or sent in SQL statements. All you need is a weak escaping mechanism (and God knows how common that is!) and you have yourself a vulnerability.
That's the basis of why I don't like basename() being suggested as a standalone, isolated, solution. Generally it *must* have additional mechanisms to screen the result for whatever specific use case the filename is wanted for. My point being that many people just don't do that.
Me, I would admit to being somewhat extreme about avoiding it as part of a validation/filtering layer. Since it touches on behavioural factors in security prevention, I find the extra work in writing a regular expression that specifically limits what I, personally, intrepret as an allowable filename is a more focused approach less likely to fall afoul of the same mistakes. I'd go so far as to say I scan for basename() use as a standard XSS/SI/Injection vector.
then what is regex?
You probably (hopefully) get my point now

. Regex can be written to be far more restrictive than basename() alone. You could argue for basename(), then regex - but I just drop the basename() use to limit the number of steps (and discourage any of the afore mentioned basename() blind dependence from other maintaining the source).