This is most certainly due to
MultiViews (part of mod_negotiation) being enabled at the shared host. It is disabled by default on Apache (so your directives “work” on your dedicated server), but some shared hosting platforms do explicitly enable this for some reason. (It makes extensionless URLs “just work” out of the box but can potentially result in SEO/security issues if you are not expecting it and often results in conflicts with mod_rewrite – as in this case.)
MultiViews basically enables extensionless URLs. When you make a request that does not map directly to a file (eg.
/internships), it looks in that directory for files that match the basename requested but with a file extension that would return the appropriate mime-type, eg.
/internships.php returns a text/html response.
RewriteRule ^internships/((A-Za-z0-9_-)+)/?$ internships.php?p=$1 (L)
MultiViews enabled, a request for
/internships/photography results in an internal subrequest for
/internships.php/photography without any query string parameters.
/photography is passed through as path-info to the
internships.php script. But since your script is looking for a
p URL parameter, it fails to respond appropriately.
MultiViews is processed before mod_rewrite is able to match the requested URL-path, so your
RewriteRule directive is effectively bypassed – since the pattern fails to match the request after MultiViews has “messed it up”!
RewriteRule ^internships/?$ internships.php (L)
Incidentally, the same applies here as well. When MutliViews is enabled this directive is not actually doing anything. But in this case, the output from MultiViews happens to be what you are expecting.
Disable MultiViews at the top of your