Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

christopher's avatar

Own Model "Wrapper" around an API

Hi there,

i am trying to get a wrapper working around an API with Laravel. So i created a Model called Server. This is my Server Model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Server extends Model
{
    protected $remote_user = 'api';
    protected $remote_pass = 'testtest';
    
    public static function connect($method, $data)
    {
        $remote_url = 'https://xxx.xx.xxx.xx:8080/remote/json.php';

        if(!is_array($data)) return false;
        $json = json_encode($data);

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_POST, 1);

        if($data) curl_setopt($curl, CURLOPT_POSTFIELDS, $json);

        // needed for self-signed cert
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        // end of needed for self-signed cert

        curl_setopt($curl, CURLOPT_URL, $remote_url . '?' . $method);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

        $result = curl_exec($curl);
        curl_close($curl);

        return $result;
    }
}

In my Controller i have this messy code

    $remote_user = 'api';
    $remote_pass = 'testtest';

    $result = Server::connect('login', array('username' => $remote_user, 'password' => $remote_pass, 'client_login' => false));
    $data = json_decode($result, true);
    $session_id = $data['response'];

    $reseller_id = 0; // this id has to be 0 if the client shall not be assigned to admin or if the client is a reseller
    $params = array(
        'company_name' => 'testcompany',
        ......
        ......
    );

    $result = Server::connect('client_add', array(
        'session_id' => $session_id,
        'reseller_id' => $reseller_id,
        'params' => $params
    ));
    $result = json_decode($result, true);
    if($result) {
        return $result;
    }

So far its working, but i want to clean up this of course. I cant get this thing working to only call

    $result = Server::connect('client_add', array(
        'session_id' => $session_id,
        'reseller_id' => $reseller_id,
        'params' => $params
    ));

in my Controller. Can someone help me how i would pass 'login', array('username' => $remote_user, 'password' => $remote_pass, 'client_login' => false) to the method so i dont have to write this everytime?

0 likes
4 replies
TheNodi's avatar

I don't know if the model is the best option here. Maybe a service container might be a better idea.

Anyway, I would clean up the code implementing additional methods so you can end up writing something like this:

$server->addClient($sessionId, $resellerId, $params);

In the Server class you build something like:

public function addClient($sessionId, $resellerId, $params) {
    if (/* check login */) {
        $this->handleLogin();
    }

    $result = $this->connect('client_add', [/*...*/]);

    return json_decode($result);
}

All the method are non-static so you can store the login key in some variable. I would also make connect function private/protected.

christopher's avatar

@TheNodi Thanks for your reply. I found a package which is already a wrapper around this API.

So this is my Controller Method:

    public function getClient()
    {
        $context = stream_context_create(array(
            'ssl' => array(
                'verify_peer'       => false,
                'allow_self_signed' => true,
                'verify_peer_name'  => false
            )
        ));
        $cp = new \GDM\ISPConfig\SoapClient('https://xxx.xxx.xx.xx:8080/remote/index.php', 'api', 'testtest', $context);
        return $cp->clientGet(Auth::id());
    }

Can i now make a Model which includes the above statement so i can only call

$cp = new Server();
$cp->clientGet(Auth::id());

How would i write this in my Model to only call new Server() or better just $this->clientGet(Auth::id)); ? I could make a __constructmethod e.g

public function __construct()
    {
        $this->context = $context = stream_context_create(array(
            'ssl' => array(
                'verify_peer'       => false,
                'allow_self_signed' => true,
                'verify_peer_name'  => false
            )
        ));
        //$this->server = new \GDM\ISPConfig\SoapClient('https://178.62.204.18:8080/remote/index.php', 'api', 'testtest', $context);
    }

Then i only have to call

    use GDM\ISPConfig\SoapClient as Server;
    ....
    ....
    public function getClient()
    {
        $cp = new Server('https://xxx.xx.xxx:8080/remote/index.php', 'api', 'testtest', $this->context);
        return $cp->clientGet(Auth::id());
    }

But then i still have to write everytime

$cp = new Server('https://xxx.xxx.xx.xxx:8080/remote/index.php', 'api', 'testtest', $this->context);

instead of $cp = new Server(); or better only $this->clientGet(Auth::id));

TheNodi's avatar
TheNodi
Best Answer
Level 11

@christopher I would keep the same concept as before even when using this API (wrapping the api into a service container). You should take a look at this video where Jeffrey faces a similar problem: Search as a Service: PHP Baby Steps (Begin at 8:30).

If you don't want to write the entire service container, you can initialize it into a service provider.

// IspConfigServiceProvider.php
<?php

namespace App\Providers;

use GDM\ISPConfig\SoapClient as Server;
use Illuminate\Support\ServiceProvider;

class IspConfigServiceProvider extends ServiceProvider
{
    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        $this->app->register(Server::class, function ($app) {
            $context = stream_context_create(array(
                    'ssl' => array(
                        'verify_peer'       => false,
                        'allow_self_signed' => true,
                        'verify_peer_name'  => false
                    )
                ));
            return new Server('https://xxx.xxx.xx.xxx:8080/remote/index.php', 'api', 'testtest', $this->context);
        });
    }
}
// Controller
    use GDM\ISPConfig\SoapClient as Server;
    /* .... */
    public function getClient(Server $server)
    {
        return $server->clientGet(Auth::id());
    }

Note: I haven't test this code and I typed it in the browser, let me know if I have mistype something.

christopher's avatar

@TheNodi Thanks for your help so far and the Link from Jeffrey. I cant really get my head around this .. :) I made a new ServiceProvider

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use GDM\ISPConfig\SoapClient as Server;

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

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->register(Server::class, function ($app) {
            $context = stream_context_create(array(
                'ssl' => array(
                    'verify_peer'       => false,
                    'allow_self_signed' => true,
                    'verify_peer_name'  => false
                )
            ));
            return new Server('https://xxx.xxx.xx:8080/remote/index.php', 'api', 'testtest', $context);
        });
    }
}

Then i registered the ServiceProvider in my app.php

    'providers' => [
     ....
    App\Providers\IspConfigServiceProvider::class,

After this i call the method in my Controller:

....
....
use GDM\ISPConfig\SoapClient as Server;

class ServerController extends Controller
{

    public function getClient(Server $server)
    {
        return $server->clientGet(Auth::id());
    }
}
....
....

But then i get the error

ErrorException in AbstractSoapClient.php line 95:
Missing argument 2 for GDM\ISPConfig\AbstractSoapClient::__construct(), called in /Users/chris/Desktop/code/sw/vendor/laravel/framework/src/Illuminate/Foundation/Application.php on line 598 and defined

Edit I fixed the error by changing $this->app->register to

$this->app->singleton

And i cleaned it a bit up and also passed the login credentials via the services config

    public function register()
    {
        $this->app->singleton(Server::class, function ($app) {
            $context = stream_context_create(array(
                'ssl' => array(
                    'verify_peer'       => false,
                    'allow_self_signed' => true,
                    'verify_peer_name'  => false
                )
            ));
            return new Server( 
                config('services.ispconfig.remote_url'),  
                config('services.ispconfig.remote_user'),  
                config('services.ispconfig.remote_password'), 
                $context);
        });
    }

Please or to participate in this conversation.