Most backend developers know about interactive modes; that certainly isn’t a secret.
jimseconde@jim-amd-u18$: php -a
gives you an active PHP shell. While an active interpreter is useful, it has one major limitation: it’s the standard library of functions of a language, not a framework or your whole application's code. You’d need to import files from all over your application. If you wanted to use Shopify’s API on the command line, for instance, you’d need to jump through all sorts of hoops line by line in order to get it up and running. How can we get a command line that loads in all of your app’s code when you open it?
From PHP interactive shell to PsySh
PsySh does exactly this. You can load it up by typing in
php artisan tinker into your command line. When it loads, it uses Composer’s autoloading functionality to put every class into memory for use by your shell. It's also fired Laravel's entry point to the app, including all of the bootstrapped features - so, features like the Service Container and Config are available:
jimseconde@jim-amd-u18$: php artisan tinker >>> config('app.my_awesome_variable'); >>> $myPusherService = app()->make('PusherService'); >>> $myPusherService->pushToQueue(['send me']);
Using the Shopify API library in a shell
In previous blog posts, I've written how to use Composer to get a REST API wrapper.. The wrapper is used to fetch and push whatever your app requires in its business logic to interact with a Shopify store (in this case). It’s baked into your app’s code though, so using something like Postman or Insomnia to manually query the API would be better suited for quick queries. With PsySh though, the API is now -just available-. Even better, you may have extended the API wrapper with bespoke functionality - now that’s available too. For example:
jimseconde@jim-amd-u18$: php artisan tinker >>> $api = new \EastsideCo\Shopify(); >>> $shopifyProduct = $api->get(‘admin/products/324235.json’)->products; >>> $localProduct = new \App\Product::create($shopifyProduct); >>> $localProduct->save();
You'll notice that PsySh also gives you interactive feedback. If you call the Eloquent
save() function for instance, as long as the entity passes validation, it will return and print true below. In the case of an API response or the result of a database query, it'll return and print a json array of the response, even if it's been set to a variable.
Your API class instance is generated the same way it would have been if you were running the whole application at runtime (because, as everything has been loaded in PsySh, technically this is exactly what has happened). So, whatever custom methods you’ve coded are now available - for example:
>>> $blogPayload = [‘09012938’,’My new blog post’]; >>> \App\API::createBlogPost($blogPayload); true >>> $api->fetchImagesByVariantId(‘90812309’)
Using the Storage driver in our command line
Here’s another example of where PsySh can be really powerful. Every Laravel class that comes with the Framework is now available - so, let’s take the File Storage system that is built on top of the powerful Flysystem PHP library. Let’s imagine you need to extract a specific SQL query for data analysis.
>>> $dataQuery = \DB::(SELECT a.id, a.title, b.title, b.price, b.sku from products a INNER JOIN variants b on a.id = b.product_id)->get(); >>> // $dataQuery is a select query returned as a .json >>> // dump out the data to the storage path >>> \Storage::disk(‘local’)->put(‘datadump.json’, $dataQuery);
On your server, your query result json is now written to
(if you’ve still using the defaults, otherwise it will be written to the
configured path for the local driver).
We’ve just used the local driver here, but if you want to, you can use any of the other drivers - such as the AWS S3 one. Want to send the same payload into an S3 bucket? Sure!
>>> \Storage::disk(‘s3’)->put(‘datadump.json’, $dataQuery);
I've found the power of an interactive shell like this to be invaluable in our day-to-day Shopify operations. For more information on PsySh and tinker, check out the docs and repos: