I'm facing an issue while trying to use Curl in Buzz for Symfony2 (I've finally managed to install it, see this post).
I use it it one on my bundles, and I've updated services.yml, adding these :
# cURL client for Buzz
buzz.client.curl:
class: Buzz\Client\Curl
public: false
calls:
- [setVerifyPeer, [false]]
# Buzz browser
buzz.browser:
class: Buzz\Browser
arguments: ['#buzz.client.curl']
And when I go and check my project's page, here's the error I get :
InvalidArgumentException: There is no extension able to load the configuration for "buzz.client.curl" (in myBundle) Looked for namespace "buzz.client.curl", found none
So from what I understand, I have to change one of Buzz's namespace declarations somewhere.
But does anybody know what, and where?
Well, my mistake, I simply didn't use the right format for my yml file.
Here is the code of the services, in case anyone has the issue. Think of the 4 spaces, that saves a lot of time...
services:
cURL client for Buzz
buzz.client.curl:
class: Buzz\Client\Curl
public: false
calls:
- [setVerifyPeer, [false]]
Buzz browser
buzz.browser:
class: Buzz\Browser
arguments: ['#buzz.client.curl']
Related
i wanna use ClientInterface in my class constructor and i give an error :
Cannot autowire service "App\Service\DelayReportService": argument "$client" of method "__construct()" references interface "Predis\ClientInterface" but no such service exists. Did you create a class that implements this interface?
seems to be i should add it manually to services.yml i added it like :
Predis\ClientInterface: '#Predis\Client'
and now i give this error:
You have requested a non-existent service "Predis\Client".
what is the solution and why symfony itself dont handle it?
you seem to be confused about how to define a service... which isn't surprising tbh
look here
https://symfony.com/doc/5.4/service_container.html#explicitly-configuring-services-and-arguments
for example
services:
App\Service\Concerns\IDevJobService:
class: App\Tests\Service\TestDevJobService
autowire: true
public: true
where
IDevJobService is an INTERFACE
and
TestDevJobService
is the actual implementation that will be auto injected
using # inside the yaml files is done to reference a service that has already been defined ELSEWHERE
https://symfony.com/doc/5.4/service_container.html#service-parameters
you probably want to watch symfonycasts services tutorial (I am not affiliated and I havent watched it myself yet (sure wish I did)).
EDIT
Predis\Client is a 3rd party class. It isn't in your App namespace or in your src folder. Symfony checks the src folder for class that it will then make to a service. See services.yaml there is a comment there, look for exclude and resource. And I'm not sure, even if you autoload it, that you can then just do #Predis\Client to reference an existing service.
be sure as well to debug your config using
php bin/console debug:autowiring
under linux you could do as well php bin/console debug:autowiring | grep Predis to find it more quickly (if it is there at all)
TL;DR
In Codeception test I am trying to $I->grabService(). Service works in controllers and has no custom config, but I get:
Fail Service App\Service\Car is not available in container
Full Story
I have a project with some Services which are basically classes, which do some processing. All the Services are accessible via service container. I am testing each class in functional suite (and some in unit) and everything worked fine till today.
So today I was adding a new Service and of course a test. I did:
root#9c80b567f681:/var/www/html# vendor/bin/codecept g:cest functional Service/Car
Test was created in /var/www/html/tests/functional/Service/CarCest.php
Test looks like this:
<?php
namespace App\Tests\Service;
use App\Service\Car;
use App\Tests\FunctionalTester;
class CarCest
{
public function _before(FunctionalTester $I)
{
$I->grabService(Car::class);
}
public function tryToTest(FunctionalTester $I)
{
}
}
Now I manually in PhpStorm create a new class. Class looks like this:
<?php
namespace App\Service;
class Car
{
}
This is output of my testing:
root#9c80b567f681:/var/www/html# vendor/bin/codecept run tests/functional/Service/CarCest.php
Codeception PHP Testing Framework v4.1.6
Powered by PHPUnit 9.2.6 by Sebastian Bergmann and contributors.
Running with seed:
App\Tests.functional Tests (1) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
✖ CarCest: Try to test (0.00s)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Time: 00:01.616, Memory: 34.00 MB
There was 1 failure:
---------
1) CarCest: Try to test
Test tests/functional/Service/CarCest.php:tryToTest
Step Grab service "App\Service\Car"
Fail Service App\Service\Car is not available in container
Scenario Steps:
1. $I->grabService("App\Service\Car") at tests/functional/Service/CarCest.php:12
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
TL;DR
Fail Service App\Service\Car is not available in container
Now most of other tests I have use the same concept: I get service in _before() and then test it. Everything passes except of any class I add today :) WTF?!?
BTW: If I replace $I->grabService(Car::class); with any other service created before, it works fine.
My services.yaml is the standard, out-of-the-box Symfony version. I always relied simply on the fact everything in src/* is already a service.
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
I spent the whole morning installing/reinstalling/restarting PC... I am completely lost and stupid. Anybody has any idea ?
EDIT:
I noticed something very interesting. If I manually add the service to services.yml and set public: true, then I can use it from Codeception. But note, that I don't have to do this for any other services I created before.
TL;DR
Problem seems to be that Symfony removes all unused services upon container compilation. You can see the code here on symfony project git page.
After I noticed, that my service works correctly when it's explicitly set to public, I started digging around that and I stumbled across git issue, where someone had the same problem. Some more digging (and talking to people smarten than me) got me to the link posted on top of this answer.
BOOM! Only took like 4 days...
I have a controller, let's say Acme\ShopBundle\Controller\ProductListController
And its definition in services.yml is as follows:
services:
Acme\ShopBundle\Controller\ProductListController:
class: Acme\ShopBundle\Controller\ProductListController
arguments: ['#product_service']
Which throws this in my log file:
User Deprecated: The "Acme\ShopBundle\Controller\ProductListController" service is private, checking for its existence is deprecated since Symfony 3.2 and will fail in 4.0.
Followed by
User Deprecated: The "Acme\ShopBundle\Controller\ProductListController" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead.
The stack trace list of files is completely inside vendor/symfony so I'm assuming something is misconfigured, but stumped as to what. Any help appreciated.
Controller service must be public:
services:
Acme\ShopBundle\Controller\ProductListController:
public: true
arguments: ['#product_service']
Why aren't you using autowiring anyway? You could register all of your controllers then:
Acme\ShopBundle\Controller\:
resource: '../src/Acme/ShopBundle/Controller' # mutatis mutandis
tags: ['controller.service_arguments']
Kindly read about new features regarding dependency management in Symfony 3.
I'm trying to define Memcache as a service in Symfony 3.4 and it doesn't appear to want to work.
This has previously worked correctly with a Symfony 2 build which is where the configuration is taken from.
I've got the following code in my services.yml:
memcache:
class: \Memcache
arguments:
persistent_id: elearn
calls:
- [ addServer, [ %memcached_host%, %memcached_port% ]]
However when attempting to clear the Symfony cache I'm getting the following error:
In AbstractRecursivePass.php line 126:
Invalid service "memcache": class "\Memcache" has no constructor.
This would make sense to me if we were trying to pass some constructor arguments in the service definition, as, like it says Memcache has no constructor but clearly we aren't doing that.
Am I missing something obvious?
Removing the
arguments
Option allowed me to get past the error. Not yet certain if memcache is behaving as expected.
I am trying to write my own messages to the log in Symfony 2.3, from anywhere, and not just the Controller (which I realize you can just do a "$this->get('logger')".
I've seen that in Symfony 1 you can use sfContext, but that class no longer seems to be a viable choice in 2.3.
Any help is appreciated.
Symfony2 has Service-oriented architecture (http://en.wikipedia.org/wiki/Service-oriented_architecture) and logger is one of service (by default Monolog). In controller you have access to service via $this->get('service_name'). Here is more info about service container: http://symfony.com/doc/current/book/service_container.html#what-is-a-service-container. If you wanna use logger in another service you have to define service and inject logger service. Example:
# section with defined service in your config.yml file (by default in config.yml)
services:
# your service name
my_service:
# your class name
class: Fully\Qualified\Loader\Class\Name
# arguments passed to service constructor. In this case #logger
arguments: ["#logger"]
# tags, info: http://symfony.com/doc/current/components/dependency_injection/tags.html
tags:
- { name: monolog.logger, channel: acme }
Additionally you should familiarize with dependency injection docs: http://symfony.com/doc/current/components/dependency_injection/index.html
I hope that helped. If not, please let me know where exactly you want to use logger.