Welcome Guest, Not a member yet? Register   Sign In
Controller naming PascalCase
#1
Sad 
(This post was last modified: 12-12-2019, 12:47 PM by RedskyThirty.)

I've lost more than 3 hours today with this issue.

I tried my project on a web server today and I didn't understand why most of my urls returned to a 404 error when I had no problem locally.
I understood that this was due to the name of my controllers which are named in PascalCase (ex: MyProfile.php). For now, the only way to solve this is to rename my controllers like this "Myprofile.php" but that disturbs me, I don't find this clean.
May be it can be solved with "mod_speling" (CheckSpelling and CheckCaseOnly) but I cannot edit the "httpd.conf" file.

What do you think about this?

I found a solution. It's not really good but it works.
I can add some routes like this:
PHP Code:
$routes->add('myprofile''App\Controllers\MyProfile::index');
$routes->add('myprofile/(:any)''App\Controllers\MyProfile::$1'); 
Reply
#2

If you develop on Windows, it finds files regardless of their case (camel, pascal, ransom).
That often breaks when running your app on Linux, as it appears you have discovered.
With URI routing, the deemed lowercase controller name has the first letter capitalized, and that is the source file that CI's loader looks for.
The proper way to get around that is with routing rules, which is the solution you came up with.

This is a feature of CI's routing.

Your mod_speling suggestion might help with Apache, but I don't know if the same is available for NGINX, nor do I suspect it would be easy to build into PHP's builtin server (thru our spark script).
Reply
#3

I didn't really noticed this since I'm developing on Linux. For my urls I always keep exactly the same name as I have with my controllers, so with cases.

So does this mean that you could have multiple controllers with the same name, just with different cases as long as its running on a Linux server? I mean its probably not a good idea to do so, but it is an interesting quirk between operating systems.
Reply
#4

(12-12-2019, 11:34 PM)berendbotje91 Wrote: I didn't really noticed this since I'm developing on Linux. For my urls I always keep exactly the same name as I have with my controllers, so with cases.

So does this mean that you could have multiple controllers with the same name, just with different cases as long as its running on a Linux server? I mean its probably not a good idea to do so, but it is an interesting quirk between operating systems.

No, I don't have controllers with same names, I would never do that ;-) But I don't want to have url with uppercases.
Reply
#5

(12-16-2019, 01:09 AM)RedskyThirty Wrote: No, I don't have controllers with same names, I would never do that ;-) But I don't want to have url with uppercases..

And you probably should not have URLs that are case-sensitive.

There are two ways to correct the problem. 1. Don't use PascalCase for controller names. Instead, use uppercase only on the first character. 2. Go ahead and use PascalCase, but define a route that points to the correct (fully PascalCase named) controller.

I believe that yet to be released documentation makes note of these options. Sorry you had to learn this the hard way.
Reply
#6

(12-19-2019, 12:02 AM)dave friend Wrote:
(12-16-2019, 01:09 AM)RedskyThirty Wrote: No, I don't have controllers with same names, I would never do that ;-) But I don't want to have url with uppercases..

And you probably should not have URLs that are case-sensitive.

There are two ways to correct the problem. 1. Don't use PascalCase for controller names. Instead, use uppercase only on the first character. 2. Go ahead and use PascalCase, but define a route that points to the correct (fully PascalCase named) controller.

I believe that yet to be released documentation makes note of these options. Sorry you had to learn this the hard way.

Yes, if you take a look at my post, I have defined some routes because I want to be consistent. All my classes are in PascalCase. I would like to do the same thing with my methods but for the moment it's not possible and I don't want to add routes for each method in each class. It would be nice if the framework could recognize methods in camelCase as snakeCase or kebabCase.
Reply
#7

I understand the interest, but I don't think it fits into the core framework because it amounts to quite a bit of extra processing for a very specific niche interest (don't worry, I'm totally picky about my code & names too). The problem is that we need to take a route and match it to an actual filename, and "mycontroller/mymethod" could be millions of different manifestations of "mYcOnTrollEr/MyMEthod" since there's no telling where the words split apart. So the fallback is a filesystem search like "foreach ($files as $name) { if strtolower($name) == strtolower($controller))... }" but that's a filesystem read on every autoroute which is a performance hit.

If you really want it you can extend Router\Router yourself. There relevant code is around line 530:
PHP Code:
    /**
     * Attempts to match a URI path against Controllers and directories
     * found in APPPATH/Controllers, to find a matching route.
     *
     * @param string $uri
     */
    
public function autoRoute(string $uri)
    {
        
$segments explode('/'$uri);

        
$segments $this->validateRequest($segments);

        
// If we don't have any segments left - try the default controller;
        // WARNING: Directories get shifted out of the segments array.
        
if (empty($segments))
        {
            
$this->setDefaultController();
        }
        
// If not empty, then the first segment should be the controller
        
else
        {
            
$this->controller ucfirst(array_shift($segments));
        } 

Notice this last part -------^^^^ that simply sets the controller to "ucfirst() of the first segment".
For kebab-case also notice the Router property translateURIDashes - it swaps dashes for underscores but could also be modified.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB