2017-01-12 9 views
5

मेरी समस्या:

तो, मैं एक वर्ग 'होम' कहा जाता है और यह वर्ग 'नियंत्रक' नियंत्रक वर्ग फैली एक निर्माता में सभी मॉडलों की आवश्यकता है। यह ठीक काम करता है।पीएचपी - वर्ग, विस्तारित वर्ग के निर्माता फोन नहीं करता है, जबकि यह एक अन्य वर्ग में ठीक काम करता है

अब मेरे पास 'लॉग इन' नामक दूसरी श्रेणी है, यह कक्षा 'नियंत्रक' भी फैली हुई है, लेकिन यह कन्स्ट्रक्टर को कॉल नहीं करती है, और मैं उलझन में हूं कि यह इस वर्ग में कन्स्ट्रक्टर को क्यों नहीं बुला रहा है।

मुझे एक वर्कअराउंड मिला है और यह है कि जब मैं ऐसा करता हूं तो Parent::__construct() के साथ लॉगिन क्लास में एक कन्स्ट्रक्टर बनाना है, सबकुछ ठीक काम करता है।

लेकिन मैं काम कर रहा हूं कि यह होम क्लास में क्यों काम करता है, और यह लॉगिन कक्षा में काम नहीं कर रहा है।

कुछ जानकारी:

घर नियंत्रक: (बिना किसी समस्या के एक)

पश्व-अनुरेखन जब मैं विस्तारित वर्ग के निर्माता कॉल करने के लिए मजबूर नहीं है:

0 Core\Controller->__construct() called at [/var/www/html/site.luukwuijster.eu/core/Router.php:26] #1 App->__construct() called at [/var/www/html/site.luukwuijster.eu/public/index.php:5]

बैकट्रैक जब मैं विस्तारित कक्षा के निर्माता को कॉल करने के लिए मजबूर कर रहा हूं:

0 Core\Controller->__construct() called at [/var/www/html/site.luukwuijster.eu/app/controllers/home.php:12] #1 Home->__construct() called at [/var/www/html/site.luukwuijster.eu/core/Router.php:26] #2 App->__construct() called at [/var/www/html/site.luukwuijster.eu/public/index.php:5]

लॉग इन नियंत्रक: (समस्याओं के साथ एक)

जब मैं विस्तारित वर्ग के निर्माता कॉल करने के लिए मजबूर कर रहा नहीं कर रहा हूँ: जब मैं निर्माता कॉल करने के लिए मजबूर कर रहा हूँ

Fatal error: Uncaught Error: Class 'App\User' not found in /var/www/html/site.luukwuijster.eu/app/controllers/login.php:21 Stack trace: #0 /var/www/html/site.luukwuijster.eu/core/Router.php(26): Login->login() #1 /var/www/html/site.luukwuijster.eu/public/index.php(5): App->__construct() #2 {main} thrown in /var/www/html/site.luukwuijster.eu/app/controllers/login.php on line 21

पश्व-अनुरेखन

Core\Controller->__construct() called at [/var/www/html/site.luukwuijster.eu/app/controllers/login.php:11] #1 Login->__construct() called at [/var/www/html/site.luukwuijster.eu/core/Router.php:26] #2 App->__construct() called at [/var/www/html/site.luukwuijster.eu/public/index.php:5]

आप देख सकते हैं, यह ठीक काम करता है जब मैं निर्माता कॉल करने के लिए मजबूर है, लेकिन जब मैंने इसे मजबूर नहीं है, यह केवल घर clas में काम करता है: विस्तारित वर्ग की रों। (होम नियंत्रक)

कोड:

होम नियंत्रक:

use App\User; 
use Core\Controller; 
use Core\DB; 

class Home extends Controller 
{ 
    public function test() 
    { 
     return User::name(); 
    } 
} 

लॉग इन नियंत्रक:

use App\User; 
use Core\Controller; 
use Core\DB; 

class Login extends Controller 
{ 

    //This is the constructor I was talking about to force the calling of 
    //the constructor in the extended class. 
    public function __construct() 
    { 
     parent::__construct(); 
    } 

    public function login() 
    { 
     return User::name(); 
    } 

} 

विस्तारित वर्ग (नियंत्रक)

namespace Core; 

class Controller 
{ 
    public $database; 

    function __construct() 
    { 

     //I have put this here to see the backtrace. 
     debug_print_backtrace(); 

     $this->database = new DB(); 

     foreach (glob('../app/models/*.php') as $model){ 

      require_once $model; 

     } 
    } 

Router.php मैं यहाँ में इस डाल दिया है क्योंकि यह यहाँ में नियम 26 पर बुलाया जाता है जब मैं विस्तारित वर्ग पर निर्माता के फोन करने के लिए मजबूर नहीं है। ($this->controller = new $this->controller;)

class App 
{ 

    protected $controller = 'home'; 
    protected $method = 'index'; 
    protected $parameters = []; 
    protected $a = 0; 

    public function __construct() 
    { 
     $url = $this->Url(); 

     if(file_exists('../app/controllers/'. $url[0] .'.php')){ 

      $this->controller = $url[0]; 
      unset($url[0]); 
     } else { 
      if (isset($url[0])) 
      die(view('error404')); 
     } 

     require_once '../app/controllers/'. $this->controller .'.php'; 

     $this->controller = new $this->controller; 

     if (isset($url[1])){ 
      if (method_exists($this->controller, $url[1])){ 
       $this->method = $url[1]; 
       unset($url[1]); 
      }else{ 
       die(view('error404')); 
      } 
     } 

     $this->parameters = $url ? array_values($url) : ['']; 

     echo call_user_func_array([$this->controller, $this->method], $this->parameters); 

    } 

    public function Url() 
    { 
     if(isset($_GET['url'])){ 
      $url = filter_var(rtrim($_GET['url'], '/'), FILTER_SANITIZE_URL); 
      $exploded_url = explode('/', $url); 
      return $exploded_url; 
     } 
    } 
} 

मेरे सवालों का:

क्यों यह ठीक होम नियंत्रक में नहीं लॉग इन नियंत्रक में काम कर रहा है, और?

और मुझे लॉग इन कंट्रोलर में वैसे ही काम करने के लिए क्या करना है?

मुझे आशा है कि सब कुछ स्पष्ट है, और यदि आपको अधिक कोड या जानकारी चाहिए तो आप टिप्पणियों में मुझसे पूछ सकते हैं।

+0

क्या आप लॉगिन :: लॉगिन() को स्थिर रूप से कॉल कर रहे हैं? –

+0

हां, मैं हूं लेकिन मैं अपनी समस्या का मुद्दा नहीं –

उत्तर

9

मैनुअल के अनुसार:

For backwards compatibility with PHP 3 and 4, if PHP cannot find a __construct() function for a given class, it will search for the old-style constructor function, by the name of the class. Effectively, it means that the only case that would have compatibility issues is if the class had a method named __construct() which was used for different semantics.

आप अपने Login कक्षा में एक login() विधि के रूप में, php का उपयोग करेगा निर्माता के रूप में। ध्यान दें कि फ़ंक्शन नाम केस-असंवेदनशील हैं।

यह भी ध्यान रखें कि यह व्यवहार php 7 में बहिष्कृत है लेकिन अभी तक इसे हटा नहीं दिया गया है।

+0

मेरा PHP संस्करण है: PHP संस्करण 7.0.8-0ubuntu0.16.04.3, इसलिए मैं PHP 7 पर हूं। –

+0

@LuukWuijster इसे PHP 7 में बहिष्कृत कर दिया गया है, अभी तक नहीं हटाया गया है, इसलिए मैंने अपना जवाब अपडेट कर दिया है। – jeroen

+0

@LuukWuijster आप या तो 'लॉगिन()' विधि का नाम बदल सकते हैं या इसे मैन्युअल रूप से कॉल कर सकते हैं। सुरक्षा के लिए मैन्युअल रूप से अभिभावक कन्स्ट्रक्टर को कॉल करने के लिए एक कन्स्ट्रक्टर जोड़ना बेहतर होगा क्योंकि अन्यथा जब आप ऑब्जेक्ट बनाते हैं तो php आपके 'लॉगिन()' विधि को कॉल करेगा और इससे अप्रत्याशित परिणाम हो सकते हैं। और भावी समस्याओं से बचने के लिए अपने 'लॉगिन()' विधि में अभिभावक कन्स्ट्रक्टर को कॉल न करें। – jeroen

1

मैनुअल राज्यों के अनुसार:

Note: Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct() within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method (if it was not declared as private).

कक्षा Login एक निर्माण इस प्रकार माता पिता निर्माण परोक्ष नहीं बुलाया जाता है। यह मुझे स्पष्ट रूप से बुलाया जाना चाहिए।

+0

ठीक है, लेकिन जब मैं लॉगिन कक्षा में '__construct()' नहीं हूं तो कन्स्ट्रक्टर को नहीं कहा जाता है। मैं केवल निर्माता को हटा सकता हूं और इसे नहीं बुलाया जाता है। –

संबंधित मुद्दे