Używanie pakietu non-laravel na Laravel 4
Czy możliwe jest włączenie do frameworka pakietu, który nie został specjalnie zaprojektowany dla L4?
Jeśli tak, to jak to się robi? Wiem, że muszę dodać pakiet do mojego composer.json
, który dodaje go do folderu vendor
, ale czy mogę go jakoś zarejestrować w tablicy providers
? czy są jakieś inne kroki konieczne?
Chciałbym użyć pakietu Google checkout pierwotnie zaprojektowanego dla Yii
2 answers
Używanie zewnętrznych pakietów composer z Laravel 4
Kiedy programiści tworzą Pakiety composer, powinni mapować automatyczne ładowanie przy użyciu standardów PSR-0 lub PSR-4. Jeśli tak nie jest, mogą wystąpić problemy z załadowaniem pakietu w aplikacji Laravel. Standard PSR-0 to:
{
"autoload": {
"psr-0": { "Acme": "src/" }
}
}
I standard PSR-4:
{
"autoload": {
"psr-4": { "Acme\\": "src/" }
}
}
Zasadniczo powyższe jest standardem informującym kompozytora, gdzie szukać plików z nazwami. Jeśli nie korzystasz z własnego przestrzenie nazw nie musisz niczego konfigurować.
scenariusz 1
PSR-0 standardowo następujące pakiety (z autoload classmap) w Laravel
Jest to proste, i na przykład użyję facebook PHP sdk, które można znaleźć:
Https://packagist.org/packages/facebook/php-sdk
Krok 1:
Dołącz pakiet do swojego kompozytora.plik json.
"require": {
"laravel/framework": "4.0.*",
"facebook/php-sdk": "dev-master"
}
Krok 2:
run: composer update
Krok 3:
Ponieważ pakiet facebook używa mapy klas, która działa po wyjęciu z pudełka, możesz natychmiast zacząć używać pakietu. (Poniższy przykład kodu pochodzi prosto z normalnego widoku. Proszę trzymać logikę z dala od widoków w aplikacji produkcyjnej.)
$facebook = new Facebook(array(
'appId' => 'secret',
'secret' => 'secret'
));
var_dump($facebook); // It works!
scenariusz 2
W tym przykładzie użyję wrappera z API PHP instagram. Tutaj trzeba wprowadzić kilka poprawek, aby uzyskać pakiet załadowany. Spróbujmy! Pakiet można znaleźć tutaj:
Https://packagist.org/packages/fishmarket/instaphp
Krok 1:
Dodaj do composer .json
"require": {
"laravel/framework": "4.0.*",
"fishmarket/instaphp": "dev-master"
}
W takim razie możesz zaktualizować program normalnie (composer update)]}
Następnie spróbuj użyć pakietu tak jak w przypadku pakietu facebook. Ponownie, jest to tylko kod w widoku.
$instagramconfig = array(
'client_id' => 'secret',
'client_secret'=> 'secret',
'access_token' => 'secret'
);
$api = Instaphp::Instance(null, $instagramconfig);
var_dump($api); // Epic fail!
Jeśli spróbujesz powyższego przykładu, otrzymasz ten błąd:
FatalErrorException: Error: Class 'Instaphp' not found in ...
Więc musimy naprawić ten problem. Aby to zrobić, możemy zbadać kompozytora instagram.json, który ma swój autoload inny niż Facebook PHP sdk miał.
"autoload": {
"psr-0": { "Instaphp": "." }
}
W porównaniu do Facebook composer.json:
"autoload": {
"classmap": ["src"]
}
(Composer obsługuje różne rodzaje autoloadingu, od plików i map klas po PSR. Spójrz na swój vendor/composer/
folder, aby zobaczyć, jak to zrobić.)
Teraz będziemy musieli załadować klasę, ręcznie. To proste, wystarczy dodać to (góra kontrolera, model lub widok):
use Instaphp\Instaphp;
Composer dump-autoload i działa!
Krok 2 (opcjonalnie)
Inną metodą jest (jeśli nie chcesz używać instrukcji "use", możesz po prostu powiedzieć composerowi, aby szukał plików prosto z twojego kodu. Po prostu zmień instancję Tak:
// reference the name-spaced class straight in the code
$api = Instaphp\Instaphp::Instance(null, $instagramconfig);
var_dump($api); // It works
Sugeruję jednak użycie instrukcji use
, aby wyjaśnić innym programistom (i waszemu przyszłemu ja), jakie (zewnętrzne) klasy/pakiety są używane w program.
scenariusz 3
Tutaj używamy Laravelów wbudowanych w kontener IOC do rejestracji dostawców usług. Należy pamiętać, że niektóre pakiety mogą nie być odpowiednie dla tej metody. Użyję tego samego pakietu Instagram, co w scenariuszu 2.
Szybkie i brudne
Jeśli nie dbasz o wzorce projektowe i dostawców usług, możesz powiązać klasę taką jak:
App::bind('Instaphp', function($app)
{
return new Instaphp\Instaphp;
});
I rozwiązujesz to jak to.
App::make('Instaphp');
Szybki i brudny koniec
Jeśli pracujesz nad większym projektem i korzystasz z interfejsów, prawdopodobnie powinieneś dalej streścić powiązania.
Krok 1:
Utwórz folder w folderze aplikacji, na przykład folder "dostawcy".
app/providers
Upewnij się, że Laravel automatycznie ładuje ten folder, możesz przekazać dodatkowe informacje do composera.json, jak to:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/providers" // this was added
]
},
Teraz Utwórz plik wewnątrz nowego folder o nazwie Instagram.php i umieść to w środku:
<?php
use Illuminate\Support\ServiceProvider;
class InstagramServiceProvider extends ServiceProvider {
public function register()
{
$this->app->bind('Instaphp', function()
{
return new Instaphp\Instaphp;
});
}
}
Uruchom ponownie composer dump-autoload i możesz użyć pakietu. Zauważ, że pakiet instagram ma final private function __construct()
, oznacza to, że nie możesz użyć tego pakietu poza oryginalną klasą bez zmiany metody konstruowania NA public. Nie mówię, że jest to dobra praktyka, i proponuję użyć scenariusza 2, w przypadku pakietu instagram.
W każdym razie, po tym można użyć pakietu w następujący sposób:
$instagramInstance = App::make('Instaphp');
$instagramconfig = array(
'client_id' => 'secret',
'client_secret'=> 'secret',
'access_token' => 'secret'
);
$instagram = new $instagramInstance();
$userfeed = $instagram->Users->feed($instagramconfig);
var_dump($userfeed); // It works!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-15 08:14:21
Dodaj "tvr/googlecheckout": "dev-master"
to do swojego composer.json
.
Uruchom composer install
, a następnie możesz użyć kontenera IoC. Niektóre przykłady kodu można znaleźć w oficjalnych dokumentach dla Laravel 4: http://four.laravel.com/docs/ioc#basic-usage
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-03 21:07:01