Try this one:
RewriteEngine On
# if requested .php file directly, then redirect to extension-less URL
# (do it on initial rewrite iteration only)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.+)\.php$ /$1 [R=301,L]
# Your "add .php file extension" rule goes below
The problem with this approach is that %{ENV:REDIRECT_STATUS}
variable may not be populated/supported by your Apache setup/configuration. Unfortunately I do not know what needs to be done to have it working.
If the above does not work, try this workaround -- it will work but not that "nice" and may fail under some circumstances (query string value is the weak point here):
RewriteEngine On
# if requested .php file directly, then redirect to extension-less URL
# (do it on initial rewrite iteration only)
RewriteCond %{THE_REQUEST} ^[A-Z]+\s.+\.php\sHTTP/.+
RewriteRule ^(.+)\.php$ /$1 [R=301,L]
# Your "add .php file extension" rule goes below
Rewrite condition in this rule is important -- without it you will have endless redirect loop, which your browser will abort at some point (unless it is not smart enough (or request is done by some poorly coded bot) and such process has to be killed manually).
It does not really matter if you place such redirect rule above or below your "add .php file extension" rule -- I just prefer keeping all 301 Redirects close to the top.