Laravel package developement error

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • scosec
  • Registratie: Februari 2016
  • Laatst online: 21:09
Goedemiddag,

Ik probeer een wrapper te maken om de SimplePie library in Laravel. Eigenlijk heel simpel maar om wat voor reden dan ook wil het niet werken. Het lijkt erop dat de Library niet geladen wordt of de serviceprovider niet doet wat hij moet doen.
De Intellisense (phpstorm) laat de class zien omdat hij wel via composer ingeladen is.

Nu ben ik letterlijk al dagen bezig om een oplossing te zoeken en ik kom hier niet doorheen. Hopelijk kan er iemand hier mij de juiste richting op sturen.

P.s. ik weet dat er bestaande packages zijn voor SimplePie en Laravel. Alleen het doel is om zelf te leren om packages te ontwikkelen.

Alvast bedankt voor de hulp!

Error:
PHP:
1
Argument 1 passed to Vpower\Feedwrapper\Eatfeed::__construct() must be an instance of SimplePie, none given, called in /Applications/AMPPS/www/theming/app/Http/Controllers/HomeController.php on line 21 and defined


Provider:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php

namespace Vpower\Feedwrapper;
use Vpower\Feedwrapper\Eatfeed;

use SimplePie;

use Illuminate\Support\ServiceProvider;


class FeedwrapperServiceProvider extends ServiceProvider
{

    protected $defer = false;
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        
        //require_once('../vendor/autoload.php');

    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {

        $this->app['simplepie'] = $this->app->share(function($app){
           return new SimplePie();
        });


        $this->app->bind(Eatfeed::class, function($app){
           return new Eatfead($app['simplepie']);

        });

    }

package composer:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
    "name": "vpower/feedwrapper",
    "description": "Reading feeds with the simplepie library",
    "authors": [
        {
            "name": "xx",
            "email": "xx@xx.nl"
        }
    ],
    "minimum-stability": "dev",
    "require": {
        "illuminate/support": "~5",
        "simplepie/simplepie": "^1.4"
    },
    "autoload": {
        "psr-4": {
            "Vpower\\Feedwrapper\\": "src"
        }
    }
}

PHP:
1
2
3
4
5
6
Normal composer:
```
"psr-4": {
            "App\\": "app/",
            "Vpower\\Feedwrapper\\": "packages/Vpower/Feedwrapper/src"
        }

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace Vpower\Feedwrapper;

use SimplePie;

class Eatfeed
{

    protected $_instance;

    public function __construct(\SimplePie $pie){
        print_r($pie);
    }

    public function readFeed(){

        echo 'got here';

    }

}

Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Je doet in je construct \SimplePie, maar je used hem al, je hoeft hem dan dus niet meer via de namespace op te halen, wil je dat wel, dan klopt de namespace niet.

[ Voor 16% gewijzigd door CH4OS op 27-06-2016 12:37 ]


Acties:
  • 0 Henk 'm!

  • scosec
  • Registratie: Februari 2016
  • Laatst online: 21:09
Dat is eigenlijk een variant van mij geweest om te kijken of dat wel wilde werken. Met en zonder backslash geeft geen ander effect helaas.

Acties:
  • 0 Henk 'm!

  • Barryvdh
  • Registratie: Juni 2003
  • Laatst online: 10-10 23:00
Waar vraag je uberhaupt die Eatfead op? Nu haal je alleen de SimplePie instance toch, dat staat helemaal los van je ServiceProvider nu.

Wat staat er *echt* op regel 21? (Je kan dus niet zomaar 'new Eatfead()' doen he)

In dit geval is je ServiceProvider uberhaupt niet nodig. Als een class niet geregistreerd is in de App container, probeert hij hem dmv de dependencies alsnog te maken. In jouw geval is de 1ste parameter van Eatfead dus een SimplePie, en SimplePie kan hij zo te zien maken zonder voorkennis (lege constructor). Dus je kan gewoon Eatfead vragen in de constructor, of in je controller method zelf:

PHP:
1
2
3
public function __construct(Eatfead $eatfead){
    dd($eatfead);
}


En als je overal dezelfde instance van Simplepie wil gebruiken, zou ik die binden aan de classname, niet gewoon 'simplepie'. Dat kan je hem namelijk 'resolven' door hem te typehinten in je classes. Dus:

PHP:
1
2
3
$this->app->singleton(SimplePie::class, function($app){
   return new SimplePie();
});

Die van Eatfeed is dan nog steeds overbodig, tenzij je iets specifieks wil doen met die constructor.
Zie ook de handleiding op https://laravel.com/docs/5.2/container De syntax is daar ook net iets anders. Maar dan zou het dus zoiets zijn:

PHP:
1
2
3
$this->app->bind(Eatfeed::class, function($app){
   return new Eatfead($app[SimplePie::class]);
});

[ Voor 34% gewijzigd door Barryvdh op 27-06-2016 13:13 ]


Acties:
  • 0 Henk 'm!

  • scosec
  • Registratie: Februari 2016
  • Laatst online: 21:09
Hé Barry,

Ik heb hem nu aangepast als volgt. Is dit nu de way to go?

Even afgezonderd dat SimplePie beter als singleton kan geïmplementeerd kan worden. Dat is stap 2 om dat even uit te zoeken.

Thanks!

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace Vpower\Feedwrapper;

use SimplePie;

class Eatfeed
{

    protected $_instance;

    public function __construct(SimplePie $pie){
        $this->_instance = $pie;
    }

    public function readFeed(){

        dd($this->_instance);

    }

}


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
use Vpower\Feedwrapper\Eatfeed;

class HomeController extends Controller
{

    protected $test;

    public function __construct(Eatfeed $test){
        $this->test = $test;
        dd($this->test);
    }

    //
    public function index(){


        $this->test->readFeed();


    }

}


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php

namespace Vpower\Feedwrapper;
use Vpower\Feedwrapper\Eatfeed;

use SimplePie;

use Illuminate\Support\ServiceProvider;


class FeedwrapperServiceProvider extends ServiceProvider
{

    protected $defer = false;
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
        
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        

        $this->app['simplepie'] = $this->app->share(function($app){
           return new SimplePie();
        });


        $this->app->bind(Eatfeed::class, function($app){
           return new Eatfeed($app['simplepie']);

        });


    }

    public function provides(){
       // return ['Feedwrapper'];
    }
}


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Eatfeed {#150 &#9660;
  #_instance: SimplePie {#151 &#9660;
    +data: []
    +error: null
    +sanitize: SimplePie_Sanitize {#152 &#9654;}
    +useragent: "SimplePie/1.4.1 (Feed Parser; http://simplepie.org; Allow like Gecko) Build/20160614054816"
    +feed_url: null
    +permanent_url: null
    +file: null
    +raw_data: null
    +timeout: 10
    +curl_options: []
    +force_fsockopen: false
    +force_feed: false
    +cache: true
    +force_cache_fallback: false
    +cache_duration: 3600
    +autodiscovery_cache_duration: 604800
    +cache_location: "./cache"
    +cache_name_function: "md5"
    +order_by_date: true
    +input_encoding: false
    +autodiscovery: 31
    +registry: SimplePie_Registry {#153 &#9654;}
    +max_checked_feeds: 10
    +all_discovered_feeds: []
    +image_handler: ""
    +multifeed_url: []
    +multifeed_objects: []
    +config_settings: null
    +item_limit: 0
    +check_modified: false
    +strip_attributes: array:14 [&#9654;]
    +add_attributes: array:3 [&#9654;]
    +strip_htmltags: array:19 [&#9654;]
  }
}

Acties:
  • 0 Henk 'm!

  • Barryvdh
  • Registratie: Juni 2003
  • Laatst online: 10-10 23:00
scosec schreef op maandag 27 juni 2016 @ 18:13:
Hé Barry,

Ik heb hem nu aangepast als volgt. Is dit nu de way to go?
Ja hij doet het nu toch? Blijft wel nog steeds het geval dat je hele ServiceProvider waarschijnlijk niet eens nodig is dus (afhankelijk van je specifiek use-case dan)

Acties:
  • 0 Henk 'm!

  • scosec
  • Registratie: Februari 2016
  • Laatst online: 21:09
Hij doet het nu inderdaad. Als ik de serviceprovider uitschakel dan blijft het werken. Maar Dependency Injection werkt toch juist op deze manier? Althans zoals ik het begrepen heb is dat de hele sleutel van de serviceproviders.

In je DomPDF package doe je toch iets vergelijkbaars?

PHP:
1
2
3
4
5
6
7
8
9
10
        $this->app->bind('dompdf', function() {
            $options = $this->app->make('dompdf.options');
            $dompdf = new Dompdf($options);
            $dompdf->setBasePath(realpath(base_path('public')));
            return $dompdf;
        });
        $this->app->alias('dompdf', Dompdf::class);
        $this->app->bind('dompdf.wrapper', function ($app) {
            return new PDF($app['dompdf'], $app['config'], $app['files'], $app['view']);
        });


Daar insert je het DomPDF toch in de PDF class? Ik had je packages al eerder bekeken maar zonder succes helaas :F

Acties:
  • 0 Henk 'm!

  • Barryvdh
  • Registratie: Juni 2003
  • Laatst online: 10-10 23:00
Klopt, maar die kan ik ook niet rechtstreeks lagen resolven, omdat ik een aantal opties moet meegeven aan de constructor.

Acties:
  • 0 Henk 'm!

  • scosec
  • Registratie: Februari 2016
  • Laatst online: 21:09
Ah werkt dat op die manier. Ik was in de veronderstelling dat je die serviceprovider altijd moest binden. Dat is dan een gebrek aan kennis / goede documentatie. Goed om te weten:)

Thanks voor je hulp!

Acties:
  • 0 Henk 'm!

  • mbenjamins
  • Registratie: December 2012
  • Laatst online: 22:06
In welke root directory zetten jullie de packages die jullie ontwikkelen?

Acties:
  • 0 Henk 'm!

  • scosec
  • Registratie: Februari 2016
  • Laatst online: 21:09
Wat je ziet in mijn composer:

"Vpower\\Feedwrapper\\": "packages/Vpower/Feedwrapper/src"

De packages folder staat op gelijke hoogte van de app/ folder.
Pagina: 1