Bear in mind that a file or directory does not "exist or not exist"
in a subdomain. It "exists or does not exist" in the
server filesytem. Therefore, you have to include the "_sites/%1" path in the filepaths to be checked.
Since %{REQUEST_FILENAME} will not include this additional path information, you have to "construct" the proper filepath to be tested.
Doing that, correcting three logic errors (a missing [OR] flag and a potential infinite loop in each rule), and simplifying the code for best performance, you'd get something like this:
RewriteEngine on
RewriteBase /
#
RewriteCond $1 !^_sites/
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com [NC]
RewriteCond %{DOCUMENT_ROOT}/_sites/%1/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/_sites/%1/$1 -d
RewriteRule ^(.*)$ /_sites/%1/$1 [L]
#
RewriteCond $1 !^(index\.php$|_sites/)
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.example.com [NC]
RewriteRule ^(.*)$ /index.php?uri=$1 [QSA,L]
The original first RewriteCond was somewhat redundant because both the first and second RewriteConds must match to invoke the rule. So I also simplified it. In other words, a request for just "example.com" with no subdomain will not match the second rule, so no provision is needed for a missing "www." in the first RewriteCond.
Note that the second rule can now never be invoked if the first rule has already been invoked. So checking for -f -d in the second rule is no longer necessary.
Since nothing is appended to the existing query string in the first rule, [QSA] is not needed.
Note also the addition of "loop prevention" RewriteConds to both rules.
Be careful here... This code allows and will rewrite requests for uppercase and mixed-case subdomains. With these rules in place, Apache will treat lowercase, uppercase, and mixed case subdomain requests as requests separate subdirectories, and upper- and mixed-case subdomain requests *will not* exist (unless you create them.) Therefore upper- and mixed-case requests will not invoke the first rule.
You may wish to add another rule to handle mis-cased subdomain requests, and exclude them from these first two rules by dropping the [NC] on the second RewriteCond in each rule, and checking for a subdomain matching "([a-z0-9]([a-z0-9\-]*[a-z0-9])?)" instead of just "([^.]+)" to improve efficiency (exists-checks are very CPU intensive, since they are calls to the OS to go check the filesystem). Therefore exists-checks should be avoided whenever possible, and should always be done last after any other RewriteConds.
Also, consider what you might want to with requests for "www.<subdomain>.example.com" or "<subdomain>.www.example.com" With the current code, those cases are not handled.
And finally, also consider what you might want to do with direct client requests for www.example.com/_sites/<subdomain>/<whatever> -- As it stands now, those would be duplicate URLs fo <subdomain>.example.com/<whatever>. I would suggest adding a rule to 301-redirect those requests to the correct subdomain-URL format. It's a bit tricky, so this should be left until all other issues cited above are decided and resolved...
Jim