एलोकेन्ट मॉडल में विधि को लागू करते समय मुझे 'नॉन-स्टैटिक मेथड' को स्टेटिकली नहीं कहा जाना चाहिए?


84

Im अपने नियंत्रक में मेरे मॉडल को लोड करने की कोशिश कर रहा है और यह कोशिश की:

return Post::getAll();

त्रुटि मिल गई Non-static method Post::getAll() should not be called statically, assuming $this from incompatible context

मॉडल में फ़ंक्शन इस तरह दिखता है:

public function getAll()
{

    return $posts = $this->all()->take(2)->get();

}

एक नियंत्रक में मॉडल को लोड करने का सही तरीका क्या है और फिर यह सामग्री है?


2 तरीके। 1, मॉडल का एक उदाहरण बनाएं और $obj->getAll()फ़ंक्शन का उपयोग करें या स्थिर करें।
itachi

5
जब आप का उपयोग करें: ::यदि आप एक विधि का उपयोग करने की कोशिश कर रहे हैं स्थिर तो अपने समारोह हस्ताक्षर के रूप में घोषित किया जाना चाहिए: public static function getAll()
Rubens Mariuzzo

@Sam, मैं आपको PHP में OOP और स्थिर विधियों के बारे में पढ़ने के लिए पांच मिनट की सिफारिश करूंगा
रुबें मेरीजियो

जवाबों:


110

आपने अपनी पद्धति को गैर-स्थिर के रूप में परिभाषित किया है और आप इसे स्थैतिक के रूप में लागू करने का प्रयास कर रहे हैं। ने कहा कि...

1. यदि आप एक स्थिर विधि को लागू करना चाहते हैं, तो आपको ::अपनी विधि को स्थिर के रूप में उपयोग करना चाहिए और परिभाषित करना चाहिए ।

// Defining a static method in a Foo class.
public static function getAll() { /* code */ }

// Invoking that static method
Foo::getAll();

2.उत्पाद, यदि आप एक उदाहरण विधि को लागू करना चाहते हैं तो आपको अपनी कक्षा का उपयोग करना चाहिए ->

// Defining a non-static method in a Foo class.
public function getAll() { /* code */ }

// Invoking that non-static method.
$foo = new Foo();
$foo->getAll();

ध्यान दें : लारवेल में, लगभग सभी एलोकेंट तरीके आपके मॉडल का एक उदाहरण देते हैं, जो आपको नीचे दिखाए अनुसार श्रृंखला विधियों की अनुमति देता है:

$foos = Foo::all()->take(10)->get();

उस कोड में हम वैधानिक रूपall से फैकेड के माध्यम से विधि को बुला रहे हैं । उसके बाद, अन्य सभी तरीकों को उदाहरण के तरीकों के रूप में बुलाया जा रहा है ।


2 विकल्प में गैर-स्थिर कैसे है?
टोबेम्से

1
इस बारे में मुझे सूचित करने के लिए @TryingTobemyself धन्यवाद। मैंने आपके सुझाव से अपना उत्तर अपडेट कर दिया।
रुबेन्स मरिज़ो

9
In Laravel, almost all Eloquent methods are defined as static.... यह एक गलत धारणा है। कोई भी स्थिर नहीं हैं।
इटैची

@ इताची, कृपया, क्या आप गलतफहमी की व्याख्या कर सकते हैं?
रुबेन्स मरिज़ो

4
हां, लारवेल में, किसी भी एलोकेंट विधियों को स्थिर के रूप में परिभाषित नहीं किया गया है , हम उनका उपयोग कर सकते हैं क्योंकि यह स्थिर के रूप में परिभाषित किया गया था, लेकिन यह एक मुखौटा है, इस बारे में और अधिक: laravel.com/docs/facades
Rubens Mariuzzo

36

स्कोप जोड़ने की कोशिश क्यों नहीं की गई? स्कोप एलोकेंट की एक बहुत अच्छी विशेषता है।

class User extends Eloquent {

    public function scopePopular($query)
    {
        return $query->where('votes', '>', 100);
    }

    public function scopeWomen($query)
    {
        return $query->whereGender('W');
    }

}

$users = User::popular()->women()->orderBy('created_at')->get();

लारवेल डॉक्स में एलोकेंट #scope


2
IMO यह स्वीकृत उत्तर होना चाहिए क्योंकि यह Laravel के लिए विशिष्ट है और Rubens उत्तर सही है लेकिन पर्याप्त विशिष्ट नहीं है।
याकूबरासदेव

8

टीएल, डॉ । आप MyModel::query()->find(10);इसके बजाय अपने प्रश्नों को व्यक्त करके इसे प्राप्त कर सकते हैं MyModel::find(10);

मेरी जानकारी के अनुसार करने के लिए, शुरू करने PhpStorm 2017.2 कोड निरीक्षण जैसे तरीकों के लिए विफल रहता है MyModel::where(), MyModel::find(), आदि (इस जाँच धागा )। यह काफी कष्टप्रद हो सकता है, जब आप अपने कोड को करने से पहले PhpStorm के Git एकीकरण का उपयोग करने की कोशिश करते हैं , PhpStorm इन स्थिर विधि कॉल चेतावनियों के बारे में शिकायत करना बंद नहीं करेगा।

इसके लिए एक सुंदर तरीका (IMOO) है, जहां भी यह स्पष्ट रूप से कॉल::query() करता है। यह आपको एक स्वत: पूर्णता और एक अच्छी क्वेरी स्वरूपण से लाभ देगा।

उदाहरण

स्निपेट जहां निरीक्षण स्थैतिक विधि कॉल के बारे में शिकायत करता है

$myModel = MyModel::find(10); // static call complaint

// another poorly formatted query with code inspection complaints
$myFilteredModels = MyModel::where('is_beautiful', true)
    ->where('is_not_smart', false)
    ->get();

अच्छी तरह से स्वरूपित कोड बिना किसी शिकायत के

$myModel = MyModel::query()->find(10);

// a nicely formatted query with no complaints
$myFilteredModels = MyModel::query()
    ->where('is_beautiful', true)
    ->where('is_not_smart', false)
    ->get();

एक गलत आईडीई चेतावनी को हटाने के लिए कोड को बदलना एक बुरा विचार जैसा लगता है। यदि आप जानते हैं कि यह सही है, तो इसे इस तरह से रखें।
zundi

@ ज़ुंडी हां सर, मैं पूरी तरह से सहमत हूं कि आईडीई को खुश करने के लिए कोड बदलना हमेशा एक अच्छा अभ्यास नहीं है, लेकिन इस मामले में, हम सिर्फ एक स्टैटिक मेथड कॉल जोड़ रहे हैं जिसे या तो तरीके से बुलाया गया होगा, (हम 'बस यहाँ स्पष्ट किया जा रहा है)। अन्यथा आपको यह करना होगा: या तो इस निरीक्षण को अक्षम करें, या किसी अन्य वर्ग को कहीं और एनोटेट करें ... (एक ऊधम! आप सहमत नहीं हैं?)
अनीस LOUNIS

1
वही, मुझे वास्तव में यह उत्तर पसंद है। मैं शुरू करने के लिए facades का एक बड़ा प्रशंसक नहीं हूं, और इस तथ्य के साथ कि PhpStorm उन्हें सही समर्थन नहीं करता है बॉक्स के बाहर मुझे कम पसंद करता है। MyModel::query()यह स्पष्ट करता है कि आईडीई को प्रसन्न करते हुए हुड के नीचे क्या हो रहा है।
म्हारासौरस

3

बस अगर यह किसी की मदद करता है, तो मुझे यह त्रुटि मिल रही थी क्योंकि मैं इस तथ्य को पूरी तरह से याद कर रहा था कि स्थानीय क्षेत्र को कॉल करते समय गुंजाइश उपसर्ग का उपयोग नहीं किया जाना चाहिए। तो अगर आपने अपने मॉडल में एक स्थानीय क्षेत्र को इस तरह परिभाषित किया है:

public function scopeRecentFirst($query)
{
    return $query->orderBy('updated_at', 'desc');
}

आपको इसे कॉल करना चाहिए:

$CurrentUsers = \App\Models\Users::recentFirst()->get();

ध्यान दें कि उपसर्ग scopeकॉल में मौजूद नहीं है।


0

आप इस तरह दे सकते हैं

public static function getAll()
{

    return $posts = $this->all()->take(2)->get();

}

और जब आप अपने कंट्रोलर फंक्शन के अंदर स्टैटिकली कॉल करते हैं ..


4
आप इसे $ एक स्थिर विधि के अंदर नहीं कर सकते हैं
लुविआस

0

मैं सचमुच अपने मामले में जवाब देने के लिए आया हूं। मैं एक प्रणाली बना रहा हूं जिसने एक बनाने की विधि को लागू किया है, इसलिए मुझे यह वास्तविक त्रुटि मिल रही थी क्योंकि मैं एलोकेंट से ओवरराइड किए गए संस्करण तक नहीं पहुंच रहा था।

उम्मीद है कि मदद?


0

जांचें कि क्या आपने मॉडल में विधि getAll () घोषित नहीं किया है। यह नियंत्रक को यह सोचने का कारण बनाता है कि आप एक गैर-स्थैतिक विधि कह रहे हैं।


0

सिंटैक्स का उपयोग करने के लिए return Post::getAll();आपके पास __callStaticअपनी कक्षा में एक मैजिक फंक्शन होना चाहिए जहां सभी स्टैटिक कॉल्स को हैंडल करें:

public static function __callStatic($method, $parameters)
{
    return (new static)->$method(...$parameters);
}

0

मूल प्रश्न का हल

आपने एक गैर-स्थैतिक विधि को सांख्यिकीय रूप से बुलाया। सार्वजनिक समारोह को मॉडल में स्थिर बनाने के लिए, इस तरह दिखेगा:

public static function {
  
}

सामान्य रूप में:

Post::get()

इस विशेष उदाहरण में:

Post::take(2)->get()

रिश्तों और दायरे को परिभाषित करते समय सावधान रहने वाली एक बात, कि मेरे पास एक ऐसा मुद्दा था जिसकी वजह से 'नॉन-स्टैटिक मेथड को स्टेटिकली नहीं कहा जाना चाहिए' त्रुटि तब होती है जब उन्हें उसी के नाम पर रखा जाता है, उदाहरण के लिए:

public function category(){
    return $this->belongsTo('App\Category');
}

public function scopeCategory(){
    return $query->where('category', 1);
}

जब मैं निम्नलिखित कार्य करता हूं, मुझे गैर-स्थैतिक त्रुटि मिलती है:

Event::category()->get();

मुद्दा, यह है कि लारवेल मेरी श्रेणी (स्कोपश्रेणी) के बजाय मेरी संबंध विधि का उपयोग कर रहा है। इस दायरे या रिश्ते का नाम बदलकर हल किया जा सकता है। मैंने रिश्ते का नाम बदलना चुना:

public function cat(){
    return $this->belongsTo('App\Category', 'category_id');
}

कृपया देखें कि मैंने विदेशी कुंजी (श्रेणी_आईडी) को परिभाषित किया है क्योंकि अन्यथा लारवेल ने इसके बजाय cat_id की तलाश की होगी, और इसे नहीं मिला होगा, क्योंकि मैंने इसे डेटाबेस में श्रेणी_आईडी के रूप में परिभाषित किया था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.