Chapters
This course is archived!
This tutorial uses a deprecated micro-framework called Silex. The fundamentals of REST are still valid, but the code we use can't be used in a real application.
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
POST: Creation, Location Header and 201
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
POST: Creation, Location Header and 201¶
Once the POST endpoint works, the client will send programmer details to the server. In REST-speak, it will send a representation of a programmer, which can be done in a bunch of different ways. It’s invisible to us, but HTML forms do this by sending data in a format called application/x-www-form-urlencoded:
POST /api/programmers HTTP/1.1
Host: localhost:8000
Content-Type: application/x-www-form-urlencoded
nickname=Geek+Dev1&avatarNumber=5
PHP reads this and puts it into the $_POST array. That’s ok for the web, but in the API world, it’s ugly. Why not, have the client send us the representation in a beautiful bouquet of curly braces known as JSON:
POST /api/programmers HTTP/1.1
Host: localhost:8000
Content-Type: application/json
{
"nickname": "Geek Dev1",
"avatarNumber": 5
}
Creating a request like this with Guzzle is easy:
// testing.php
// ...
$nickname = 'ObjectOrienter'.rand(0, 999);
$data = array(
'nickname' => $nickname,
'avatarNumber' => 5,
'tagLine' => 'a test dev!'
);
$request = $client->post('/api/programmers', null, json_encode($data));
$response = $request->send();
echo $response;
echo "\n\n";
The second null argument is the request headers to send. We’re not worried about headers yet, so we can just leave it blank.
Coding up the Endpoint¶
Back in the ProgrammerController class, let’s make this work by doing our favorite thing - coding! First, how do we get the JSON string passed in the request? In Silex, you do this by getting the Request object and calling getContent() on it. Let’s just return the data from the endpoint so we can see it:
// src/KnpU/CodeBattle/Controller/Api/ProgrammerController.php
// ...
public function newAction(Request $request)
{
$data = $request->getContent();
return $data;
}
Tip
Your framework will likely have a shortcut for getting the request content or body. But if it doesn’t, you can get it by using this strange bit of code:
$data = file_get_contents('php://input');
This is a special stream that reads the request body. For more details, see php.net: php://.
Try running our testing.php file again:
$ php testing.php
This time, we see the JSON string being echo’ed right back at us:
HTTP/1.1 200 OK
...
Content-Type: text/html; charset=UTF-8
{"nickname":"ObjectOrienter31","avatarNumber":5}
Creating the Programmer Resource Object¶
Awesome! I’ve already created a Programmer class, which has just a few properties on it. I also created simple classes for the other two resources - Project and Battle. We’ll use these later.
In newAction, we have the JSON string, so let’s decode it and use the data to create a new Programmer object that’s ready for battle. We’ll use each key that the client sends to populate a property on the object:
// src/KnpU/CodeBattle/Controller/Api/ProgrammerController.php
// ...
public function newAction(Request $request)
{
$data = json_decode($request->getContent(), true);
$programmer = new Programmer($data['nickname'], $data['avatarNumber']);
$programmer->tagLine = $data['tagLine'];
// ...
}
Note
Do not forget to add use KnpU\CodeBattle\Model\Programmer; namespace for the Programmer class at the beginning of the ProgrammerController.php.
My app also has a really simple ORM that lets us save these objects to the database. How you save things to your database will be different. The key point is that we have a Programmer class that models how we want our API to look, and that we can somehow save this:
// src/KnpU/CodeBattle/Controller/Api/ProgrammerController.php
// ...
public function newAction(Request $request)
{
$data = json_decode($request->getContent(), true);
$programmer = new Programmer($data['nickname'], $data['avatarNumber']);
$programmer->tagLine = $data['tagLine'];
$programmer->userId = $this->findUserByUsername('weaverryan')->id;
$this->save($programmer);
return 'It worked. Believe me - I\'m an API';
}
At the bottom, I’m just returning a really reassuring message that everything went ok.
Faking the Authenticated User¶
I’ve also added one really ugly detail:
$programmer->userId = $this->findUserByUsername('weaverryan')->id;
Every programmer is created and owned by one user. On the web, finding out who is creating the programmer is as easy as finding out which user is currently logged in.
But our API has no idea who we are - we’re just a client making requests without any identification.
We’ll fix this later. Right now, I’ll just make every programmer owned by me. Make sure to use my username: it’s setup as test data that’s always in our database. This test data is also known as fixtures.
Ok, the moment of truth! Run the testing script again:
$ php testing.php
HTTP/1.1 200 OK
Host: localhost:8000
...
Content-Type: text/html; charset=UTF-8
It worked. Believe me - I'm an API
The message tells us that it probably worked. And if you login as weaverryan with password foo on the web, you’ll see this fierce programmer-warrior in the list.
Status Code 201¶
But no time to celebrate! Our response is a little sad. First, since we’ve just created a resource, the HTTP elders say that we should return a 201 status code. In Silex, we just need to return a new Response object and set the status code as the second argument:
// src/KnpU/CodeBattle/Controller/Api/ProgrammerController.php
// ...
public function newAction(Request $request)
{
// ...
$this->save($programmer);
return new Response('It worked. Believe me - I\'m an API', 201);
}
Running the testing script this time shows us a 201 status code.
Location Header¶
And when we use the 201 status code, there’s another rule: include a Location header that points to the new resource. Hmm, we don’t have an endpoint to get a single programmer representation yet. To avoid angering the RESTful elders, let’s add a location header, and just fake the URL for now:
// src/KnpU/CodeBattle/Controller/Api/ProgrammerController.php
// ...
public function newAction(Request $request)
{
// ...
$this->save($programmer);
$response = new Response('It worked. Believe me - I\'m an API', 201);
$response->headers->set('Location', '/some/programmer/url');
return $response;
}
If you stop and think about it, this is how the web works. When we submit a form to create a programmer, the server returns a redirect that takes us to the page to view it. In an API, the status code is 201 instead of 301 or 302, but the server is trying to help show us the way in both cases.
Try the final product out in our test script:
$ php testing.php
HTTP/1.1 201 Created
...
Location: /some/programmer/url
Content-Type: text/html; charset=UTF-8
It worked. Believe me - I'm an API
Other than the random text we’re still returning, this endpoint is looking great. Now to GET a programmer!
80 Comments
Hey jlchafardet!
Hmm, I'm not sure. When that external API returns this 400 error, it should include details about what went wrong... it could many different things, like the "body" is malformed, or the data is formed correctly, but some key in their doesn't make sense to the API.
But, I do notice that you're creating the JSON manually... which (as long as you haven't made any syntax errors) is fine, just a lot of work :). You would normally use the json
option instead of body
for this and set it to an array. This is mentioned in this section - https://symfony.com/doc/current/http_client.html#uploading-data - inside a box if you scroll a little.
Cheers!
I am still learning about the whole httpclient and httpclientinterface, yes I tried using the json type instead of "body", but got the same error.
I think all I need is to read a little more and dedicate a little extra time to it instead of being as impatient as I'm being right now :D
when i execute the testing.php file i am redirected to the login page is it normal ?
oki its good it was because in scurity.yml the A in api was writen in capital
Nice catch!
Why is this on the Symfony *3* track, I wonder?
Hey Maksym!
We have it because it's still relevant (the changes from Symfony 2 to 3 - other than the directory structure changes - are quite minor). We have a few other things on the Symfony 3 track that are done with later versions of Symfony 2, but are still relevant. And in this case, we *do* switch to Symfony 3 during Course 4 - so the series is a bit mixed!
Cheers!
Hello how i do the REST API with syfmony 3.* version. currently example is with symfony 2.6. how i can migtae to syfmony 3?
Hey Prakash,
Everything is mostly the same. First of all you need to upgrade composer dependencies according to the Symfony 3. To do that, you should ensure that bundles you use in project support Symfony 3.x, check its composer.json file to see symfony/framework-bundle: ^2.0 || ^3.0
. If you see "^3.0" - it should work and you can do upgrade.
P.S. Don't forget to fix all deprecations in 2.8 before upgrading. We have a tutorial about it: <a href="http://knpuniversity.com/screencast/symfony3-upgrade">
How to Upgrade to Symfony 2.8, then 3.0</a>.
Cheers!
In my testing.php i had to make the line $response = $client->post('/app_dev.php/api/programmers'); How do I change that?
Hi Scott!
Because you're using Symfony, if you use the built-in web server command from Symfony (php app/console server:run) it will start a built-in web server where it *defaults* to using app_dev.php - without you needing to have it in the URL. Alternatively, you can setup any other web server locally to have the same behavior.
BUT, more generally, we do talk about this in our Symfony REST tutorial. In our tests, we use a hook into Guzzle that automatically prepends the URL: http://knpuniversity.com/sc.... In episode 4 (which I'm recording right now), I've updated the code that hooks into Guzzle to work for Guzzle version 6: http://knpuniversity.com/sc...
I hope that helps - good question!
That helped me!! i couldn't navigate the website so i changed nginx to serve app_dev.php and its working. But isn't there a way to prepend all routes with /app_dev.php within symfony?
thanks!
Awesome! So, whether or not you need the app_dev.php is *all* about your web server :). Ultimately, if you want the "dev" environment to be executed, then the web/app_dev.php must be executed. As I mentioned earlier, if you use the built-in web server with Symfony, it pre-configures things so that you *don't* need the app_dev.php at the beginning of all of the URLs: if there is no file in the URL, then it is "rewritten" to use app_dev.php. If you use Apache, for example, you could setup rewrite rules locally to do the same. In fact, there is a web/.htaccess file that sets up rewrite rules in Apache so that app.php is used by default (which is what you want in production). I know a lot of people that setup their web server locally to automatically rewrite to app_dev.php so that they don't need to have it in their URL.
Cheers!
Thank you pointing in the right direction! Although by just changing only the nginx/sites-enabled/restexample.dev i had some troubles (404 errors) with testing env because i think the real path was "domain/app_dev.php/app_test.php/api/whatever" but Victors(knp) advice in video13/course1 helped me. i will try to manipulate paths from .htaccess from now on but so long all ok.
When I did a composer install, I did receive a ton of deprecation notices. But the app runs except in the browser console it says GET http://localhost:8000/vendor/font-awesome/fonts/fontawesome-webfont.ttf?v=4.0.3 404 (Not Found)
Hey John!
Yep - there are a few libraries that still work fine, but are older versions at this point. The only one that I know is actually *deprecated* is Guzzle. We use guzzle/guzzle at version 3, but the latest version os guzzlehttp/guzzle (yes it has a different name now) at version 6! We don't technically use this library for the API... but we do use it for *testing* the API. In the Symfony REST tutorial - starting on episode 4 (http://knpuniversity.com/sc... we use the latest and greatest version 6. So, if you're curious about the differences, you can compare. Otherwise, if you're here for the API stuff, I wouldn't worry about it :).
About the 404 on the Font file, I'm not sure about that. If you download the starting code, there *is* a web/vendor/font-awesome/fonts/fontawesome-webfont.ttf file in the project - so it should be loading this just fine. It shouldn't affect anything either way (you might just be missing some cute icons) but the 404 is mysterious!
Cheers!
Hello! I get the following error: Catchable fatal error: Object of class GuzzleHttp\Psr7\Response could not be converted to string in \testing.php on line 37. there is "echo $response". how should I convert my response object to string?
Hey Andjii!
The tutorial uses guzzle/guzzle version 3.7, not guzzlehttp/guzzle at version 6 (which I'm guessing you are using). You can use the old, guzzle/guzzle just fine, or use the new library. But in that case, you'll need to do a little bit of translating for the new version of the library. Check out this comment for a few more details, including a gist with a version of testing.php that should work with the latest version :). http://knpuniversity.com/screencast/rest/post#comment-2298542838
But, to finally answer your question, you can't just echo the $response in Guzzle 6 (as you know), but you can print the body:
echo $response->getBody();
In some ways, the new version of the library is not as user-friendly as the old version. You can also check out this Response debugging function that we use in the Symfony REST tutorial: https://gist.github.com/weaverryan/8bcf209fe11290b01185195280661e97#file-apitestcase-php-L130
Cheers!
Why is better option to use the `testing.php` file instead Postman? Seems dirty to me.
Hi Roberto!
Actually, I would argue that testing.php is not better than Postman :). However, we will soon (in the next chapters in this tutorial) take the code from testing.php and turn them into true functional tests for our API. I believe this *is* better than Postman, because we now have a test suite that we can run at any time.
Cheers!
Hello, where this is config file for setting up the database connection? I called $this->save($programmer), but it wasn't showing up.
Hey Yan,
I suppose if your DB credentials were invalid - you'll get a 500 error. Probably, you have permissions problem, we use SQLite for this course. The DB configuration is located in "src/KnpU/CodeBattle/Application.php" - see configureParameters() method. Make sure "data/code_battles.sqlite" file exist and have read/write permissions. Or you can simply change drive to pdo_mysql and fill MySQL credentials to use MySQL db instead.
Cheers!
Hi Victor,
I have code_battles.sqlite, and the whole data directory got 777 permission. test.php runs without error or exception. Still not saving anything.
so I update the configureProviders() function to use mysql. Then when I visit localhost:8000/login, I got 2002 error.
"An exception occured in driver: SQLSTATE[HY000] [2002] No such file or directory"
I check the database, its empty. How can I get the schema? Usually, I do that via the symfony console doctrine:schema:update, but there is no such tool.
Hey Yan,
An exception occured in driver: SQLSTATE[HY000] [2002] No such file or directory
You configure MySQL credentials incorrectly. Here's the correct parameters, you should fill them in with your correct credentials:
// Doctrine DBAL
$this->register(new DoctrineServiceProvider(), array(
'db.options' => array(
'driver' => 'pdo_mysql',
'host' => 'localhost',
'port' => 3306,
'dbname' => 'rest',
'user' => 'root',
'password' => '',
),
));
The "path" option is something unique for SQLite, so you don't need to use it for MySQL database.
About schema, yeah, that's the worst part - you need to create it manually because this application do not have Symfony console support. That's why all the schema and initial data are commited to the repository, i.e. lies in the data/code_battles.sqlite file.
Cheers!
Hello
When I run in cmd: composer install
I have error
Deprecation Notice: The callback Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::buildBootstrap declared at C:\OpenServer\domains\start.symfony.rest\vendor\sensio\distribution-bundle\Sensio\Bundle\DistributionBundle\Composer\ScriptHandler.php accepts a Composer\Script\CommandEvent but post-install-cmd events use a Composer\Script\Event instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc... in phar://C:/OpenServer/modules/php/PHP-7.0-x64/composer.phar/src/Composer/EventDispatcher/EventDispatcher.php:316
How can I to fix this notice?
Hey Nina
Try updating composer and then the dependency
composer self-update
composer update sensio/distribution-bundle
Cheers!
In the symfony documentation they don’t use Guzzle for functional tests and they extended webtestcase. Is this the best practice now?
Hey Shaun,
Yes, Symfony recommends this way. But if you like Guzzle a lot - you can use Guzzle of course ;)
Cheers!
please don't do zooming file view, becouse sometimes loosing and dont understand what file is edit author, so need go back to find out what file currently is
Hey Igor Kalamurda!
Good feedback! We actually don't zoom anymore on newer videos - glad that's preferable :).
Cheers!
Hi everyone.. I get this error:
PHP Fatal error: Uncaught Error: Class 'GuzzleHtpp\Client' not found in /home/henri/myprojects/symfonyrest/testing.php:5
Stack trace:
#0 {main}
thrown in /home/henri/myprojects/symfonyrest/testing.php on line 5
and this is my testing.php :
'http://localhost:8000',
'defaults' => [
'exceptions' => false,
]
]);
$response = $client->post('/api/programmers');
echo $response;
echo "\n\n";
any suggestion?
Yo Henry,
I think it was just a misprint :) Look closely to "GuzzleHtpp" - it should be "GuzzleHttp", i.e. "GuzzleHttp\Client".
Cheers!
Ups.. sorry my bad! >.<
Thank you victor
For anyone using Guzzle version 6, this is what I used to get this working:
require __DIR__.'/vendor/autoload.php';
$client = new \GuzzleHttp\Client([
'base_uri' => 'http://localhost:8000',
'defaults' => [
'exceptions' => false,
]
]);
$response = $client->post('/api/posttests');
echo $response->getStatusCode() . ' ' . $response->getReasonPhrase();
echo "\n";
foreach ($response->getHeaders() as $name => $values) {
echo $name . ': ' . implode(', ', $values) . "\r\n";
}
echo $response->getBody();
echo "\n\n";
Hey Shaun,
Thanks for sharing it with others. Yes, you need to use "base_uri" now, but why do you set exceptions to false? And why do you echo all that info? Is it just temporary for debugging purposes?
Cheers!
When I try to run testing.php I get the following error:
Shauns-MBP:knpu-symfony-rest-example shaunthornburgh$ php testing.php
Fatal error: Cannot use lexical variable $eventName as a parameter name in /Users/shaunthornburgh/Documents/Development/knpu-symfony-rest-example/vendor/guzzlehttp/guzzle/src/Event/Emitter.php on line 48
Hey Shaun T.!
Ah, unfortunately, it looks like a bug in Guzzle and PHP 7! https://github.com/guzzle/g....
What version of Guzzle are you using? I believe this bug was fixed in 5.3.1 (and was not present in 6).
Cheers!
Thanks Ryan, I'm not sure how I can check as I don't see it in my composer.json...
Hey Shaun,
You can see a lot of information by executing "composer info package_name" command, e.g. to see the version of guzzlehttp/guzzle, run:
composer info "guzzlehttp/guzzle"
Cheers!
Thanks @Ryan and @Victor, how can I update the Guzzle version if it's not in composer.json ?
I tried:
Shauns-MBP:knpu-symfony-rest-example shaunthornburgh$ composer update vendor/guzzlehttp:5.3.1
Package "vendor/guzzlehttp:5.3.1" listed for update is not installed. Ignoring.
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Hey Shaun T.!
Hmm, interesting! I wonder if the Guzzle bug also exists in the older version that we're using in this tutorial. What do you see when you run these 2 commands?
```
composer info "guzzlehttp/guzzle"
composer info "guzzle/guzzle"
```
We'll figure this out! If there *is* an old bug with the version of Guzzle we're using in this tutorial, then unfortunately, the best solution will be to use a newer version of Guzzle. That's only annoying because it means that code in this tutorial won't work exactly :/. The code in this tutorial is a few years old now, so it's starting to show its age (but the explanations and philosophies we teach are still very good).
Cheers!
Thanks for getting back to me Ryan, this is what I get:
Shauns-MBP:Development shaunthornburgh$ cd knpu-symfony-rest-example/
Shauns-MBP:knpu-symfony-rest-example shaunthornburgh$ composer info "guzzlehttp/guzzle"
name : guzzlehttp/guzzle
descrip. : Guzzle is a PHP HTTP client library and framework for building RESTful web service clients
keywords : client, curl, framework, http, http client, rest, web service
versions : * 5.2.0
type : library
license : MIT License (MIT) (OSI approved) https://spdx.org/licenses/M...
source : [git] https://github.com/guzzle/g... 475b29ccd411f2fa8a408e64576418728c032cfa
dist : [zip] https://api.github.com/repo... 475b29ccd411f2fa8a408e64576418728c032cfa
names : guzzlehttp/guzzle
autoload
psr-4
GuzzleHttp\ => src/
requires
guzzlehttp/ringphp ~1.0
php >=5.4.0
requires (dev)
ext-curl *
phpunit/phpunit ~4.0
psr/log ~1.0
Shauns-MBP:knpu-symfony-rest-example shaunthornburgh$ composer info "guzzle/guzzle"
[InvalidArgumentException]
Package guzzle/guzzle not found
show [--all] [-i|--installed] [-p|--platform] [-a|--available] [-s|--self] [-N|--name-only] [-P|--path] [-t|--tree] [-l|--latest] [-o|--outdated] [-m|--minor-only] [-D|--direct] [--strict] [-f|--format FORMAT] [--] [<package>] [<version>]
Shauns-MBP:knpu-symfony-rest-example shaunthornburgh$
Hey Shaun T.!
Ah, perfect - then the situation shouldn't be too bad! Try this:
composer update guzzlehttp/guzzle
Even though this isn't in your composer.json, it's required by other libs, and you should be able to update it. Let me know if it works out!
Cheers!
Same again unfortunately :(
composer update guzzlehttp/guzzle
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files
> Incenteev\ParameterHandler\ScriptHandler::buildParameters
Updating the "app/config/parameters.yml" file
Deprecation Notice: The callback Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::buildBootstrap declared at /Users/shaunthornburgh/Documents/Development/knpu-symfony-rest-example/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Composer/ScriptHandler.php accepts a Composer\Script\CommandEvent but post-update-cmd events use a Composer\Script\Event instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes in phar:///usr/local/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php:316
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::buildBootstrap
Deprecation Notice: The callback Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache declared at /Users/shaunthornburgh/Documents/Development/knpu-symfony-rest-example/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Composer/ScriptHandler.php accepts a Composer\Script\CommandEvent but post-update-cmd events use a Composer\Script\Event instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes in phar:///usr/local/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php:316
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache
Clearing the cache for the dev environment with debug true
Deprecation Notice: The callback Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installAssets declared at /Users/shaunthornburgh/Documents/Development/knpu-symfony-rest-example/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Composer/ScriptHandler.php accepts a Composer\Script\CommandEvent but post-update-cmd events use a Composer\Script\Event instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes in phar:///usr/local/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php:316
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installAssets
Trying to install assets as symbolic links.
Installing assets for Symfony\Bundle\FrameworkBundle into web/bundles/framework
The assets were installed using symbolic links.
Installing assets for Sensio\Bundle\DistributionBundle into web/bundles/sensiodistribution
The assets were installed using symbolic links.
Deprecation Notice: The callback Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installRequirementsFile declared at /Users/shaunthornburgh/Documents/Development/knpu-symfony-rest-example/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Composer/ScriptHandler.php accepts a Composer\Script\CommandEvent but post-update-cmd events use a Composer\Script\Event instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes in phar:///usr/local/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php:316
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installRequirementsFile
Deprecation Notice: The callback Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::removeSymfonyStandardFiles declared at /Users/shaunthornburgh/Documents/Development/knpu-symfony-rest-example/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Composer/ScriptHandler.php accepts a Composer\Script\CommandEvent but post-update-cmd events use a Composer\Script\Event instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes in phar:///usr/local/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php:316
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::removeSymfonyStandardFiles
Deprecation Notice: The callback Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::prepareDeploymentTarget declared at /Users/shaunthornburgh/Documents/Development/knpu-symfony-rest-example/vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Composer/ScriptHandler.php accepts a Composer\Script\CommandEvent but post-update-cmd events use a Composer\Script\Event instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes in phar:///usr/local/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php:316
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::prepareDeploymentTarget
Shauns-MBP:knpu-symfony-rest-example shaunthornburgh$ php testing.php
Fatal error: Cannot use lexical variable $eventName as a parameter name in /Users/shaunthornburgh/Documents/Development/knpu-symfony-rest-example/vendor/guzzlehttp/guzzle/src/Event/Emitter.php on line 48
Shauns-MBP:knpu-symfony-rest-example shaunthornburgh$
Hey Shaun,
Hm, first of all I wonder what PHP version do you use? Execute "php -v" to see.
OK, that's a bit weird, but I'm starting to get lost here. Let me to summarize all we have and formulate a few steps for you:
1. Let's obviously require "guzzlehttp/guzzle" if it can't be found by Composer to update. Since you're on Guzzle 5.2.0, let's avoid BC breaks and require "^5.3":
composer require "guzzlehttp/guzzle:^5.3"
2. Composer should install the latest 5.3.1 version of Guzzle lib. To double check, run:
composer info guzzlehttp/guzzle
IN the output you should see "versions : * 5.3.1" which means you're on the latest available version of Guzzle in 5.x branch for now.
Then when you run "php testing.php" that "Fatal error: Cannot use lexical variable $eventName..." should be gone. If no, let us know, then you probably should upgrade to the latest version of Guzzle in 6.x branch or use a different PHP version.
Cheers!
This worked for me!
Thanks for your answer!
I had same issue as Shaun
and command:
composer require "guzzlehttp/guzzle:^5.3"```
throws:
Problem 1
- Installation request for guzzlehttp/ringphp (locked at 1.0.7) -> satisfiab le by guzzlehttp/ringphp[1.0.7].
- guzzlehttp/guzzle 5.3.0 requires guzzlehttp/ringphp ^1.1 -> satisfiable by guzzlehttp/ringphp[1.1.0].
- guzzlehttp/guzzle 5.3.1 requires guzzlehttp/ringphp ^1.1 -> satisfiable by guzzlehttp/ringphp[1.1.0].
- guzzlehttp/guzzle 5.3.2 requires guzzlehttp/ringphp ^1.1 -> satisfiable by guzzlehttp/ringphp[1.1.0].
- Conclusion: don't install guzzlehttp/ringphp 1.1.0
- Installation request for guzzlehttp/guzzle ^5.3 -> satisfiable by guzzleht tp/guzzle[5.3.0, 5.3.1, 5.3.2].```
so I did:
composer require "guzzlehttp/ringphp:^1.1"```
and then:
composer require "guzzlehttp/guzzle:^5.3"`
and it works.
Hey Pawel,
Thanks for sharing your solution with others! Yeah, looks like you needed to upgrade "guzzlehttp/ringphp" to v1.1.x at least since you have only 1.0.7. Nice error message from Composer btw!
Cheers!
I gave up on the previous tutorial on REST here using Silex because the tutorial is ancient and it felt like I was running into a lot of compatibility issues due to the project being so old. I ended up finding another tutorial elsewhere and then coming back here for the next version of REST.
The trouble is now I seem to be running into the same problems here. When I googled a problem I was having with set up today, I found the following answer on stack overflow.
"The older version of Annotations is referring to the opcache.load_comments setting in php.ini, which does not exist in PHP 7:"
Isn't there a way to set up a virtual env that can be easily cloned so everyone is starting in the same place? If not, maybe tutorials should be pulled down after they reach a certain age.
"Houston: no signs of life"
Start the conversation!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"silex/silex": "~1.0", // v1.3.2
"symfony/twig-bridge": "~2.1", // v2.7.3
"symfony/security": "~2.4", // v2.7.3
"doctrine/dbal": "^2.5.4", // v2.5.4
"monolog/monolog": "~1.7.0", // 1.7.0
"symfony/validator": "~2.4", // v2.7.3
"symfony/expression-language": "~2.4" // v2.7.3
},
"require-dev": {
"behat/mink": "~1.5", // v1.5.0
"behat/mink-goutte-driver": "~1.0.9", // v1.0.9
"behat/mink-selenium2-driver": "~1.1.1", // v1.1.1
"behat/behat": "~2.5", // v2.5.5
"behat/mink-extension": "~1.2.0", // v1.2.0
"phpunit/phpunit": "~5.7.0", // 5.7.27
"guzzle/guzzle": "~3.7" // v3.9.3
}
}
hey guys! I dont quite know where to ask this, so I'll ask here.
I'm trying to POST a json body request to an external url API based on Graphql
but I keep getting bad request response (HTTP/1.1 400 Bad Request returned for ).... I am very very new to the httpclientinterface and httpclient as a whole. so any pointers on how to do this would be amazing.