4

I've been building a web app of my own for a while now, but have completely hit against the wall with a fatal error in PHP.

Short story: I'm working on the login / user section of the project. login.php handles the login stuff, while student.php handles the account stuff.

When trying to complete doLogin, I achieve the fatal error that states student::getProfile() is an "undefined method". student::getProfile() is called as part of validate() inside the login class.

Any assistance would be greatly appreciated! Thanks :)

EDIT: With the help of @deceze I've been able to narrow the issue down to the fact that Composer isn't autoloading all of my classes; only some. Would anyone be able to assist?

EDIT 2: I checked autoload_classmap.php which was generated by Composer, and all my core classes and models are listed! If they're listed in the classmap, why isn't Composer loaded them?


project directory

application/
    config/
    controller/
    core/
        (core items such as auth, app, view rendering + view controller)
    model/
        (speciality functions such as login, registration + user)
    view/
public/
    index.php
    .htaccess
vendor/
    autoload.php
composer.json
.htaccess

note: /public/index.php calls `require '../vendor/autoload.php';`

composer.json

"autoload": {
    "psr-4": {
        "": [
            "application/core/",
            "application/model/"
        ]
    }
}
Tomas Votruba
  • 23,240
  • 9
  • 79
  • 115
Damian W
  • 568
  • 2
  • 4
  • 14
  • include that student.php file inside login.php at the start. – Pratik Joshi May 09 '15 at 13:02
  • @deceze `Call to undefined method student::getProfile() in login.php` – Damian W May 09 '15 at 13:02
  • @jQuery.PHP.Magento.com it's already 'included' using Composer's PSR-4 autoloader. – Damian W May 09 '15 at 13:03
  • 3
    This *should* work. The only explanation really is that the file is not being included. – deceze May 09 '15 at 13:04
  • **NOTE**: in login.php instead of `$result = login::validate($student_email, $student_password);` USE `$result = self::validate($student_email, $student_password);` Its better approach – Pratik Joshi May 09 '15 at 13:07
  • @deceze that's what I've been saying to myself over and over again, it's driving me crazy. I'm 110% positive it's included through Composer as if I try to include it myself I obtain a "Cannot redeclare" error. – Damian W May 09 '15 at 13:07
  • 1
    Simply confirm whether the file is being included by adding an `echo "I'm included!"` to it. The only other explanation would be namespaces, and/or invisible characters in your code somewhere; i.e. the name of the class or function is actually different. – deceze May 09 '15 at 13:11
  • @RyanVincent No I'm not using NameSpaces. Should I be? – Damian W May 09 '15 at 13:11
  • @DamianWorsdell can you pls do what deceze says? – Pratik Joshi May 09 '15 at 13:17
  • In validate method you're missing return $result – Simon May 09 '15 at 13:21
  • @deceze @jQuery.PHP.Magento.com I've added an `error_log("xxx")` to each of my class files, and it seems only *some* of them are being autoloaded by Composer. I'm totally at a loss. My composer.json file is simply ` "autoload": { "psr-4": { "": ["application/core/", "application/model/"] } } ` . `student.php` and `login.php` are both in the `/model/` directory. – Damian W May 09 '15 at 13:22
  • 1
    So you've narrowed down the problem to a problem with your autoloader. Please rewrite the question accordingly to focus on that, this isn't going to be solved in comments. – deceze May 09 '15 at 13:24
  • @deceze thanks! Question updated :) – Damian W May 09 '15 at 13:35

1 Answers1

1

After much tedious searching, I've found the error in my ways - and it's pretty silly!

I have a controller named student while also having a model named student, and as such I was inadvertently trying to call a class that's technically already being called. As such, it was looking in the first student class for the function, rather than the other which actually contained that specific function.

Composer doesn't realise if there is already a class with that name pre-declared, and just negates it without any entry in the PHP error log.

To avoid this error - and any further class name mixups in the future - I decided to use individual namespaces for both core classes and model classes. This separates those classes into 'sub-sections' as such, allowing the use of classes named the same (albeit in different namespaces).


PHP Manual: Namespaces

Sitepoint: How to Use PHP Namespaces, Part 1: The Basics

Damian W
  • 568
  • 2
  • 4
  • 14