2017-04-04 6 views
0

いくつかのコンテキストでは、今日(私はプロバイダの設定が可能な)Cacheのようなファサードを実装する方法を理解するのに苦労していましたが、提供されていない一般的なフォールバックプロバイダ。Factoryクラスの前でファサードを実装するLaravel 5.4

今、私は基本的なインフラストラクチャを稼働させていますが、実装は面倒です。 default()またはprovider()を呼び出すだけで臭いがあります。しかし、ここにギャップを埋めるために欠けている概念やものがあります。ここで

Implementing similar functionality to Cache::disk('x') in Laravel

私がやったものです。

本当に)私は常にデフォルトを(使用する必要がされて悩ませている何
// Factories\SMSFactory.php 

namespace App\Factories; 

use App\IError; 


class SMSFactory 
{ 
    public static function default() 
    { 
     $defaultProvider = config('sms.default_provider'); 
     return self::provider($defaultProvider); 
    } 

    public static function provider($providerId) 
    { 
     $providerClass = config('sms.' . $providerId); 

     if (class_exists($providerClass)) 
     { 
      return (new $providerClass); 
     } 

     return new class implements IError { 

     }; 
    } 

} 

// sms.php (config) 

return [ 
    /** 
    * Set the default SMS provider for the application 
    */ 
    'default_provider' => 'smsglobal', 

    /** 
    * Map the SMS provider to a class implementation 
    */ 
    'smsglobal' => 'App\SMSGlobal\SMSGlobal', 
]; 

// Providers\SMSServiceProvider.php 

namespace App\Providers; 

use Illuminate\Support\ServiceProvider; 


class SMSServiceProvider extends ServiceProvider 
{ 
    /** 
    * Bootstrap the application services. 
    * 
    * @return void 
    */ 
    public function boot() 
    { 
     // 
    } 

    /** 
    * Register the application services. 
    * 
    * 
    * @return void 
    */ 
    public function register() 
    { 
     $this->app->bind('sms', 'App\Factories\SMSFactory'); 
    } 
} 

// Facades\SMS.php 

namespace App\Facades; 

use Illuminate\Support\Facades\Facade; 

class SMS extends Facade 
{ 
    protected static function getFacadeAccessor() 
    { 
     return 'sms'; 
    } 
} 


// app.php 

App\Providers\SMSServiceProvider::class, 

# and in aliases 

'SMS' => App\Facades\SMS::class, 


// Controllers/TestController.php 


namespace App\Http\Controllers\TestController; 

use App\Http\Controllers\Controller; 
use Illuminate\Http\Request; 

use App\Facades\SMS; 


class TestController extends Controller 
{ 
    public function sendSMS($destination, $message) 
    { 
     $data = $request->all(); 

     return SMS::default()->send([ 
      'destination' => $destination, 
      'message' => $message, 
     ]); 
    } 
} 

...

私はファサードは、静的クラスとして動作するが、それは、このような方法でそれを設定することが可能であることを理解私はこのような電話をすることができますか?

SMS::send($args); 

// When I want to use another gateway 
SMS::provider('nexmo')->send($args); 
+0

プロバイダクラスでは、別のプロバイダに変更する方法がありますか? –

+0

サービスプロバイダはファクトリをバインドします。したがって、現在、sms.php設定ファイルで 'new-gateway'が定義されている限り、SMS :: provider( 'new-gateway')でゲートウェイを切り替えることができます。その部分はすべて動作しています – Trent

答えて

1

あなたのSMSのファクトリクラスで__callメソッドを使用することができ、そしてそれに応じて変更する必要があります。

class SMSFactory 
{ 
    public function default() 
    { 
     $defaultProvider = config('sms.default_provider'); 

     return $this->provider($defaultProvider); 
    } 

    public function provider($providerId) 
    { 
     $providerClass = config('sms.' . $providerId); 

     if (class_exists($providerClass)) 
     { 
      return (new $providerClass); 
     } 

     return new class implements IError { 

     }; 
    } 

    public function __call($name, $arguments) 
    { 
     if (!method_exists($this, $name)) { 
      $object = [$this->default(), $name]; 
     } else { 
      $object = [$this, $name]; 
     } 

     return call_user_func_array($object, $arguments); 
    } 
} 

SMSFactoryクラスは静的メソッドなどの静的メソッドは、ファサードを介してアクセスできる必要はありません。

+0

私は、静的メソッドとしてファサードを呼び出すメソッドを作ることができます。これは、新しいインスタンスを生成し、そのインスタンスでコマンドを実行しようとします。これを私のコードに入れたら、未定義のメソッドSMSFactory :: send()を呼び出します。コントローラから、SMS :: send( 'Testing')を実行します。 – Trent

+0

メソッドが存在しないときにもcall_user_func_arrayに気付きました。関数名をインスタンスに渡していないので、$ [default、$ name]、$ argumentsに変更しましたが、まだ問題は解決していません – Trent

+0

OK - この関数は呼び出されていない(PHP7)... – Trent

関連する問題