You still need something to "forward" all virtual requests to a physical file.
The idea is that any URI that doesn't match a physical file or folder on disk is rewritten (usually through mod_rewrite) to your index.php file (it's usually your index file so a direct call to the index works too), and it appends the URI to the path or as a query string parameter:
RewriteCond %{REQUEST_FILENAME} !-f # Not a real file
RewriteCond %{REQUEST_FILENAME} !-d # Not a real folder
RewriteRule ^(.*)$ index.php/$1 [L] # Rewrite to index.php, with a leading slash, followed by the URI
Alternatively, you can use a standard error document handler (still in .htaccess or apache config, but no need for mod_rewrite!):
<IfModule !mod_rewrite.c>
ErrorDocument 404 /index.php
</IfModule>
Now that control is passed to uniformly to an index.php file, you need a router mechanism to match the route to the correct controller. Ideally, you'd have a list of static and dynamic routes. Static routes are direct matches to the URI, and dynamic would be regular expression matches. Check your static routes first, as it's as simple as a single hash lookup, while you'll have to loop through all the dynamic routes.
For performance, it's nice to put your more common dynamic routes at the beginning of the list, and the obscure ones at the end.