Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Security & the User Class

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Yeaaaa! You've done it! You've made it to the tutorial where we get to build a security system with Symfony. This stuff is cool. Seriously, these days, the topic of security is gigantic! Just think about authentication: you might need to build a traditional login form, or a token-based API authentication system, or two-factor authentication or authentication across an API to a Single Sign-On server or something I've never even dreamed of before! For authorization, there are roles, access controls and more.

Woh. So we're going to write some seriously fun code in this tutorial. And it will be especially fun, because there are some new cool toys in Symfony's security system that make it nicer than ever to work with.

Coding Along!

As always, to become a true Symfony security geek... and to obtain the blueprint to the Deathstar, you should definitely code along with me. Download the course code from this page. When you unzip it, you'll find a start/ directory that has the same code that you see here. Follow the README.md file for all the important setup details.

Oh, and if you've been coding along with me in the Symfony series so far, um, you're amazing! But also, be sure to download the new code: I made a few changes since the last tutorial, including upgrading to Symfony 4.1 and improving our fixture system. More on that later.

Anyways, the last setup step will be to open a terminal, move into the project and run:

php bin/console server:run

to start the built in web server. Ok: head back to your browser and open our app by going to http://localhost:8000.

Hello The SpaceBar! Our awesome intergalactic real news site that helps connect alien species across this side of the Milky Way.

Installing Security & Upgrading MakerBundle

Our first goal in this tutorial is to create an authentication system. In other words: a way for the user to login. No matter how you want your users to authenticate - whether it's a login form, API authentication or something crazier - the first step is always the same: brew some coffee or tea. The second step is also always the same: create a User class.

To do this, we're going to use a brand-spanking new feature! Woo! Find your terminal and run:

composer update symfony/maker-bundle

Version 1.7 of MakerBundle comes with a new command that will make our life much easier. Yep, there it is: 1.7. The new command is called make:user - try it:

php bin/console make:user

Ah! It explodes! Of course! Remember: in Symfony 4, our project starts small. If you need a feature, you need to install it. Run:

composer require security

Ah, check it out: this library has a recipe! When Composer finishes... find out what it did by running:

git status

A new config file! Check it out: config/packages/security.yaml. This file is super important. We'll start talking about it soon.

Creating the User Class with make:user

Before we run make:user again, add all the changed files to git and commit with a message about upgrading MakerBundle & adding security:

git add .
git commit -m "Upgraded MakerBundle and added security"

I'm doing this because I want to see exactly what the make:user command does.

Ok already, let's try it!

php bin/console make:user

Call the class User. Second question:

Do you want to store user data in the database

For most apps, this is an easy yes... because most apps store user data in a local database table. But, what if your user data is stored on some other server, like an LDAP server or a single sign-on server? Well, even in those cases, if you want to store any extra information about your users in a local database table, you should still answer yes. Answer "no" only if you don't need to store any user information to your database.

So, "yes" for us! Next: choose one property on your user that will be its unique display name. This can be anything - it's usually an email or username. We'll talk about how it's used later. Choose email.

And, the last question: is our app responsible for checking the user's password? In some apps - like a pure API with only token authentication, users might not even have a password. And even if your users will be able to login with a password, only answer yes if this app will be responsible for directly checking the user's password. If you actually send the password to a third-party server and it checks if it's valid, choose no.

Remember when I mentioned how complex & different modern authentication systems can be? That's why this command exists: to help walk us through exactly want we need.

I'm going to choose "No" for now. We will add a password later, but we'll keep things extra simple to start.

And... we're done! Awesome! This created a User entity, a Doctrine UserRepository for it, and updated the security.yaml file.

Let's check out these changes next!

Leave a comment!

96
Login or Register to join the conversation
Antonio Avatar
Antonio Avatar Antonio | posted 3 years ago

Are you planning on doing a Ldap tutorial? The docs on Symfony's site is not that clear and there're not that many resources online on this. :/

1 Reply

Hey Antonio!

We're not planning one at this time, but I'd be happy to help if you have some specific questions - and if I know the answers ;).

Cheers!

Reply

Hey Ryan, can I ask you a question about ldap?

I have a symfony 5 application that works just great on centos 8 (on azure) with Apache 2.4.46.

But now we want ldap to do the authentication.
I have used ldap before with symfony 3 on a windows server. This works great. We even have 'single signon' working

But the problem is, i can not get it to work with centos 8, apache and symfony 5.

  • I have modules installed on centos8. like ldap_module and authnz_ldap_module.
  • I also have http2 protocol working.
  • We have ssl working
  • installed ldap: "symfony/ldap": "5.1.*",
  • security bundle: "symfony/security-bundle": "^5.1",

Also created a virtual host on centos.


<VirtualHost *:8443>
        Protocols h2 http/1.1
        ServerName xxx
        DocumentRoot /var/www/html/portal/public
        DirectoryIndex /index.php
        
        <  Directory /var/www/html/portal/public  >
                AllowOverride All
                Order Allow,Deny
                Allow from All
                Satisfy any
                AuthType Basic
                AuthName "LDAP authentication"
                AuthBasicProvider ldap
               Require valid-user
        </Directory>

This is my security.yaml.

    
firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        main:
            stateless: true
            http_basic_ldap:
                service: Symfony\Component\Ldap\Ldap
                dn_string: 'uid={username},dc=example,dc=com'

This is services.yaml:

    
Symfony\Component\Ldap\Ldap:
        arguments: ['@Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']
    Symfony\Component\Ldap\Adapter\ExtLdap\Adapter:
        arguments:
            -   host: xxx
                port: 389
                encryption: ssl
                options:
                    protocol_version: 3
                    referrals: false

I do get the ldap popup that asks for my username and password. But is won't open up the application. The popup is coming back.
In symfony logs i get no error messages.
In apache error logs i get

[Tue Aug 25 07:03:46.027059 2020] [lbmethod_heartbeat:notice] [pid 36808:tid 140326978189504] AH02282: No slotmem from mod_heartmonitor<br />[Tue Aug 25 07:03:46.066243 2020] [mpm_event:notice] [pid 36808:tid 140326978189504] AH00489: Apache/2.4.46 (codeit) OpenSSL/1.1.1g PHP/7.3.21 configured -- resuming normal operations<br />[Tue Aug 25 07:03:46.066298 2020] [core:notice] [pid 36808:tid 140326978189504] AH00094: Command line: 'httpd -f /etc/httpd/conf/httpd1.conf'<br />

Can you help me out please? I REALLY would appreciate this!

Thanks in advance and keep up this great work you're doing!!!

1 Reply

Hi truuslee!

I'm far from an LDAP expert (more of a novice really!, but since you seem to know it well, let's see if we can figure this out together ;).

The first question that comes to mind is: does the Symfony application ever get triggered. I'm curious if that HTTP basic popup is coming from Symfony or if it's coming from Apache. You could determine this by opening your public/index.php file and putting a die('executed'); line right after the opening PHP tag.

What I don't know (because I'm such a novice on this topic) is what config you're supposed to have in Apache to get this to work. Do you need that Apache LDAP configuration at all? I really don't know and I could absolutely be mistaken, but it almost looks like we're implementing LDAP HTTP basic authentication at the Apache level (which may not be working correctly) and then again on the Symfony level. The Symfony http_basic_ldap should be able to handle everything on its own (as long as it can communicate to the LDAP server). I don't think (?) that Apache should be involved in any ways. But, these are guesses :).

Let me know if any of this makes sense, and if the Symfony app is actually being executed.

Cheers!

1 Reply

Thank you Ryan for your quick response. You're the best.

The die('executed') is being reached. On Apache I don't have to do any configuration at all? Only make sure the ldap modules are installed?
All the ldap configuration needs to be done in Symfonies service.yaml and security.yaml?

Many many thanks !!!

Reply

Hi truuslee!

> On Apache I don't have to do any configuration at all? Only make sure the ldap modules are installed?

Unfortunately, I have no idea! But yes, this is my "feeling". If you have all the ldap configuration and connection information inside Symfony, this means that Symfony is talking directly to the LDAP server. If that's the case, then I can't think of why you would need anything in Apache. A similar thing happens with normal (non-LDAP) HTTP Basic: Apache *does* have a feature to use HTTP basic directly inside of it. But usually, you don't use that at all, and instead configure Symfony to do HTTP basic.

> The die('executed') is being reached

Ok! You've already told me that the Symfony logs don't have an errors. I would double-check that again - look very closely for anything related to security. There may not be anything, but I'm trying to be sure. Also, completely remove the LDAP stuff from Apache. Does the HTTP basic popup still happen? Im trying to determine if the HTTP basic popup is coming from Apache or Symfony.

Finally, you may need to do some debugging in the core of Symfony to figure out what's failing. In theory, after Symfony shows you the HTTP basic popup, when you submit, Symfony should grab the username and password that were entered and call the checkAuthentication() method in this class - https://github.com/symfony/...

I would add a die() statement in there to make sure it's being executed. And you may also be able to figure out why/when it's failing if it IS executed.

Let me know what you find out!

Cheers!

Reply

Hello Ryan,

I'm debugging LdapBindAuthenticationProvider.php
What's really weird is that it says i've entered a bad password.

`catch (ConnectionException $e) {

   print('bad password');die;
   throw new BadCredentialsException('The presented password is invalid.');

}
`
This is in the function 'checkAuthentication'.

I tried with other credentials, same error.
Did a print of the username and password. It's all there.

But at least now i know where it's going bad.
If you any idea why this is happening, what i have to check, please write to me.
Many thanks in advance.

Cheers!!!

Reply

Hey truuslee!

Excellent debugging! Hmm. So, once you're inside of checkCredentials(), this is all raw, Ldap logic, which I imagine would indicate some sort of misconfiguration... or something. This is where my lack of LDAP knowledge renders me a bit useless ;).

But, there is one thing that stands out: the BadCredentialsException is being thrown inside a catch for a ConnectionException. I would add dd($e) right before the exception is thrown so that you can actually see the error. It may be that there are multiple possible reasons for this error (maybe the LDAP server can't even be reached!) and that, for security reasons, all of those are being caught and given the generic "The presented password is invalid." error.

Let me know what you find :).

Cheers!

Reply

Hello Ryan,
I can run the code on development now. Before today i could only debug this code on production. And that is very difficult.
So i think i will find the problem now. Thanks for all your help and keep up the good work!!!

With kind regards,
Annemieke Buijs

Reply

Hey Ryan,

Thanks for helping me out.
I'm the only programmer here, so sometimes it just helps to talk to somebody about the problems i'm facing.

This is a dump of the '$e'

`Symfony\Component\Ldap\Exception\ConnectionException {#320 â–¼
#message: "<b>Can't contact LDAP server"</b>
#code: 0
#file: "/var/www/html/portal/vendor/symfony/ldap/Adapter/ExtLdap/Connection.php"
#line: 70
trace: {â–¼

/var/www/html/portal/vendor/symfony/ldap/Adapter/ExtLdap/Connection.php:70 {â–¶}
/var/www/html/portal/vendor/symfony/ldap/Ldap.php:40 {â–¼
  Symfony\Component\Ldap\Ldap->bind(string $dn = null, string $password = null) …
  › {
  ›     $this->adapter->getConnection()->bind($dn, $password);
  › }
  arguments: {â–¼
    $dn: "uid=abu,dc=example,dc=com"
    $password: "xxx"
  }
}
/var/www/html/portal/vendor/symfony/security-core/Authentication/Provider/LdapBindAuthenticationProvider.php:104 {â–¶}
/var/www/html/portal/vendor/symfony/security-core/Authentication/Provider/UserAuthenticationProvider.php:80 {â–¶}
/var/www/html/portal/vendor/symfony/security-core/Authentication/AuthenticationProviderManager.php:81 {â–¶}
/var/www/html/portal/vendor/symfony/security-http/Firewall/BasicAuthenticationListener.php:86 {â–¶}
/var/www/html/portal/vendor/symfony/security-http/Firewall/AbstractListener.php:27 {â–¶}
/var/www/html/portal/vendor/symfony/security-http/Firewall.php:111 {â–¶}
/var/www/html/portal/vendor/symfony/security-http/Firewall.php:84 {â–¶}
/var/www/html/portal/vendor/symfony/event-dispatcher/EventDispatcher.php:270 {â–¶}
/var/www/html/portal/vendor/symfony/event-dispatcher/EventDispatcher.php:230 {â–¶}
/var/www/html/portal/vendor/symfony/event-dispatcher/EventDispatcher.php:59 {â–¶}
/var/www/html/portal/vendor/symfony/http-kernel/HttpKernel.php:133 {â–¶}
/var/www/html/portal/vendor/symfony/http-kernel/HttpKernel.php:79 {â–¶}
/var/www/html/portal/vendor/symfony/http-kernel/Kernel.php:196 {â–¶}
/var/www/html/portal/public/index.php:28 {â–¼
  › $request = Request::createFromGlobals();
  › $response = $kernel->handle($request);
  › $response->send();
  arguments: {â–¶}
}

}
}
`

And this is the dump of the ldap parameter in the same class.

`Symfony\Component\Ldap\Ldap {#174 â–¼
-adapter: Symfony\Component\Ldap\Adapter\ExtLdap\Adapter {#175 â–¼

-config: array:3 [â–¼
  "host" => "xxxl"
  "port" => 389
  "options" => array:1 [â–¼
    "protocol_version" => 3
  ]
]
-<b>connection: null</b>
-entryManager: null

}
}`

I think a major issue is that the connection parameter is empty?
Thank you in advance !

Greetz,
Annemieke

Reply

Hey Annemieke!

Thanks for helping me out.
I'm the only programmer here, so sometimes it just helps to talk to somebody about the problems i'm facing.

My pleasure - I know how this can be ;)

This is a dump of the '$e'
Symfony\Component\Ldap\Exception\ConnectionException {#320 â–¼
#message: "Can't contact LDAP server"

Ok, this is kind of what I was expecting - that there is some connection issue. So, it appears - by looking in the code a bit for how the different errors are handled - that this is not an "invalid credentials" error. Instead, it's simply some sort of connection issue with the LDAP server.

But first, you mentioned:

I think a major issue is that the connection parameter is empty?

MAYBE. This property remains null until you try to connect to LDAP. So, depending on when you dumped the Ldap object (e.g. you dumped it before anyone tried to use it), it's totally normal for it to be null. You could actually play around with this Ldap object a bit if you want:


$ldap = // the Ldap object that you dumped earlier
$ldap->bind($dn, $password); // this line will likely explode - it's what the security system is doing internally

I don't know if being able to play with the Ldap object more directly will help... I just think there is some sort of connection error. And so, I would back up and see if you are able to connect to the Ldap server in general. You could do this 2 different ways:

a) Create a little play.php script anywhere on your filesystem, and see if you can manually use ldap_connect() and ldap_bind() with your connection config to successfully connect to the LDAP server - https://www.php.net/manual/en/ldap.examples-basic.php - run the file at your terminal via php play.php

b) Install the OpenLDAP utilities - https://www.digitalocean.com/community/tutorials/how-to-manage-and-use-ldap-servers-with-openldap-utilities - and see if you can connect to the LDAP server at the command line.

I'm quite (but not absolutely, as LDAP is not my expertise) certain that there is a connection problem to the LDAP server. Either it's simply not accessible, or we have the wrong connection config.

Cheers!

Reply

Hey Ryan, thanks again for all your help.
The Play.php works fine on production. No problem.

But the function ldap_bind in LdapBindAuthenticationProvider.php is somehow different?

in play.php:
ldap_bind($ds, $dn, $password)

in LdapBindAuthenticationProvider.php:
ldap_bind($dn, $password)

As you can guess, the connection works, the ldap bind works in play.php, but ldap_bind does not work in LdapBindAuthenticationProvider.php

You still want to help me?

Greetz from the Netherlands (stroopwafels)

Reply

Hi truuslee !

Excellent debugging! And, I love stroopwafels ;). We were in Amsterdam last year for SymfonyCon, so we enjoyed many fresh stroopwafels ;).

Ok, so we know the connection to the LDAP server on production is working - that's an awesome step. Now, you mentioned:

in play.php:
ldap_bind($ds, $dn, $password)

in LdapBindAuthenticationProvider.php:
ldap_bind($dn, $password)

That's not quite accurate. In LdapBindAuthenticationProvider, the code is $this->ldap->bind($dn, $password) - https://github.com/symfony/symfony/blob/c649bfa9d48a07f00bcd1e47aaad5018e88148bf/src/Symfony/Component/Security/Core/Authentication/Provider/LdapBindAuthenticationProvider.php#L104 - that is not calling the ldap_bind function directly. Instead, this ultimately calls this https://github.com/symfony/symfony/blob/c649bfa9d48a07f00bcd1e47aaad5018e88148bf/src/Symfony/Component/Ldap/Adapter/ExtLdap/Connection.php#L54-L60 - and that calls the ldap_bind. I'm mentioning this to show that, in both play.php and LdapBindAuthenticationProvider, eventually, the ldap_bind() function is being called with the same 3 arguments - so it's not that Symfony is missing the first argument :).

Here is what I would do next (if you're able to do this - ideally you would do it on production, or at least on a server where you KNOW that ldap_bind() is working): go into the core Ldap connection class - https://github.com/symfony/symfony/blob/c649bfa9d48a07f00bcd1e47aaad5018e88148bf/src/Symfony/Component/Ldap/Adapter/ExtLdap/Connection.php#L54-L60 - and hack in some temporary debugging code:

A) Right before this line, I would add var_dump($dn, $password);die; and then test. This will tell you if the $dn and $password are what you expect (and what you have in play.php).

B) Next, right before this line - https://github.com/symfony/symfony/blob/c649bfa9d48a07f00bcd1e47aaad5018e88148bf/src/Symfony/Component/Ldap/Adapter/ExtLdap/Connection.php#L136 - add var_dump($this->config['connection_string']);die;. This will tell you if the argument that you're passing to ldap_connect() is what you expect.

As you can see, now that you've verified that you ARE able to talk to the LDAP server and you have it working in play.php, it seems to me that we must just have some invalid configuration somewhere in our Symfony app. That's what I'm trying to debug :).

Cheers!

Reply

Hi Ryan, (Mr. Stroopwafel). I was there at the SymfonyCon in Amsterdam. That was a real nice con. And i listened to your speech, the rest of the day I had stroopwafels on my mind!

I've got ldap working. It was indeed just getting the config right. So it's up and running now on production. Ldap is a great tool, but because i didn't create it myself there's a lot i don't know. But mainly thanks to you i relaxed and started to look good at the code again.
Thank you very much Ryan, please keep doing what you 're doing.
And maybe until the next Con!

Annemieke

Reply

Hey Annemieke!

> I was there at the SymfonyCon in Amsterdam. That was a real nice con

:). I was wondering if you were! I also really enjoyed that conference - and I particularly enjoyed Amsterdam (unfortunately, I didn't have time to visit other parts of the country).

> I've got ldap working. It was indeed just getting the config right

Woohoo! Yea, this is a particularly hard area because Symfony, sort of, "hides" the real error from us (remember, it originally was "The presented password is invalid") so that *real* errors aren't leaked to the user. Nice job sticking with it pulling back the pieces until the bad config presented itself :).

> And maybe until the next Con!

I sure hope so - whenever that will be!

Cheers!

Reply
Abelardo Avatar
Abelardo Avatar Abelardo | posted 3 years ago | edited

Hi there!
When you run this command:
composer require security
is possible that Symfony warns you:
Package symfony/lts is abandoned, you should avoid using it. Use symfony/flex instead.<br />
Simply you should remove from composer.json since symfony/flex is installed by default since its version 4
Brs

1 Reply

Hey AbelardoLG,

Yeah, now when symfony/lts package is abandoned - you can get rid of it. First, make sure you have symfony/flex in your dependencies and then you can remove it with "composer remove symfony/lts". But it's not required, so you skip this warning, especially if you're working on a demo project you downloaded from SymfonyCasts.

Cheers!

2 Reply
Abelardo Avatar
Abelardo Avatar Abelardo | Victor | posted 3 years ago | edited

Hi there, victor : Thanks for your words! ;)

Reply
Abelardo Avatar
Abelardo Avatar Abelardo | posted 3 years ago

Hi there!

With Symfony 4.4, the ManagerRegistry class is deprecated (found on UserRepository). Take into consideration. :)

What should the replacement be?

Best regards.

1 Reply

Hey AbelardoLG,

Yes, according to this deprecation warning: https://github.com/doctrine... - you need to use "\Doctrine\Persistence\ManagerRegistry" instead of "Doctrine\Common\Persistence\ManagerRegistry" since doctrine/persistence 1.3.

I hope this helps!

Cheers!

1 Reply

For some reason, installing the security bundle failed with:
PHP Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 67108864 bytes) in phar:///usr/local/Cellar/composer/1.9.1/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223

If you have the same problem, you can fix it running the following:
php -d memory_limit=-1 $(which composer) require security

It basically allows Composer to eat all the memory it wants. I don't know why it happens or if there's a better fix though.

1 Reply

Hey Alexandre,

Thank you for this tip! Actually, there's even easier solution, check Composer docs for more info: https://getcomposer.org/doc...

Cheers!

2 Reply
weaverryan Avatar weaverryan | SFCASTS | posted 4 years ago | edited

Hey there!

Hmm, you want to create some code in the production environment? What's your use-case? Normally you should do all coding in the dev environment. Can you tell me?

To answer your question - MakerBundle is only (by default) enabled in the dev environment - because it's a tool for development. You could override that (though I don't recommend it) by modifying the config/bundles.php and changing the 'dev' => true to 'all' => true next to the MakerBundle entry.

Cheers!

1 Reply
Abelardo Avatar

I solved my issue.

Thanks for replying a Sunday evening! :)

Best regards.

Reply
Abelardo Avatar

Hi.
I am building a login form with security bundle (yes, I am trying to replicate your example but for my app). I understand you mean I should export the creation script of the table user in dev and import into the mysql in prod environment, right?

I have to create a table in prod in order to pair my entity user into mysql (it's the engine database I am using).

Reply
Cheshire Avatar
Cheshire Avatar Cheshire | posted 1 year ago | edited

I'm further along in the course, but I just noticed there is an extra line in my security.yaml that I'm not sure where it came from. It's the provider line under the main firewall:


main: 
    anonymous: true
    provider: app_user_provider

What inserted this line, and is it necessary, what does it do? Or, could you kindly point me to where it was discussed if the lessons mentioned it and I overlooked? Thank you

Reply

Hey Cheshire Y.

That line was automatically added after creating the User class. You can check it here: https://symfonycasts.com/sc...
What it basically does is to reload the User from session at the start of a request, and for other internal functionalities of Symfony (like the SwitchUser mechanishm)

Cheers!

Reply
Default user avatar
Default user avatar Why doesn't this work | posted 2 years ago | edited

I'm getting an error when running composer install

Specifically, this happens during cache:clear:`
!! In EntityManagerInterface.php line 33:
!!
!! Attempted to load interface "ObjectManager" from namespace "Doctrine\Common\Persistence".
!! Did you forget a "use" statement for another namespace?
!!
!!
!!
``

Here is the complete install log: https://pastebin.com/7SAr7Rmc

Reply

Hey there!

Hmm. Did you download the course code from this page? Or are you using something different? I just checked the downloadable code on this page, and it *did* install without any issues. However, I noticed that some of the versions of my libraries (from the code download) are different than your version - for example "doctrine/persistence" (which is related to your error) is 1.1.0 in your pastebin but is 1.3.7 in both the start and finish code from the download.

Let me know - I *do* know this error (Doctrine split some of their libraries into smaller pieces, and so sometimes you can get annoying dependency mismatches).

Cheers!

Reply
Default user avatar
Default user avatar Why doesn't this work | weaverryan | posted 2 years ago | edited

Thanks for the reply. Turns out Windows had the maximum path length limit turned on, and composer just silently failed to write those files instead of warning me.

However, I'm now getting a new error:

Executing script cache:clear [KO]
 [KO]
Script cache:clear returned with error code 1
!!
!!  In FileLocator.php line 71:
!!
!!    The file "services.xml" does not exist (in: C:\Users\username\Google Drive\Technische Keuzemodule (SymfonyCasts
!!     keuzevak)\Uitwerkingen\5. Symfony Security - Beautiful Authentication, Powerful Authorization\vendor\doctrine\doct
!!    rine-migrations-bundle\DependencyInjection/../Resources/config/).```



I've done `git diff --no-index "the config directory from the download" "the config directory after finishing the previous course"` and the only difference were in a few files that had nothing to do with doctrine.


Neither the current course that I'm trying to install nor the previous one had a file named `services.xml`, so I've got no idea what's going wrong here. Google isn't giving me very useful results.
Reply

Hey Why!

Look at the path! From the error you can see that services.xml file does not exist in vendor/ directory. I'd recommend you to remove your vendor/ directory completely and install the dependancies again. You literally should do:

$ rm -rf vendor/
$ composer install

Does it help? Btw, which version of Composer do you use? You can check it with "composer --version" command. If you're using Composer 2.0 - it might be related to the problem. Try to install the dependencies using the 1.x Composer, you can download the latest 1.x version of Composer from the official website right to the project dir and execute it from there like:

$ php ./composer.phar install

Does it help?

Cheers!

Reply
Default user avatar
Default user avatar Why doesn't this work | Victor | posted 2 years ago

Didn't, already tried.

But I finally found the cause, was again related to path name length. Windows did actually have that services.xml file, but PHP failed to read it or recognize that it existed. Shortening the path name fixed it.

Reply

Interesting... so PHP couldn't read the path because it was too long?

Reply
Emad B. Avatar
Emad B. Avatar Emad B. | posted 2 years ago | edited

Hi there .

i have error when i run
composer install
in first time to start codig :)

this error :
<a href="https://drive.google.com/file/d/1LEbCH1KI4JWasKe-bZThvOm63kYMBUFY/view?usp=sharing&quot;&gt;https://drive.google.com/file/d/1LEbCH1KI4JWasKe-bZThvOm63kYMBUFY/view?usp=sharing&lt;/a&gt;

so i run
composer update

then i got this error
<a href="https://drive.google.com/file/d/1Md89t-E3jsaVKYBPL0uZh3-BfI6JH7he/view?usp=sharing&quot;&gt;https://drive.google.com/file/d/1Md89t-E3jsaVKYBPL0uZh3-BfI6JH7he/view?usp=sharing&lt;/a&gt;

my setup is PHP 7.3.21 , <br />Symfony CLI version v4.18.4 ,<br />Composer version 2.0.0-alpha3

any idea what wrong :) thank you

Reply

Hey Emad,

Unfortunately, I can't see your images because the access is restrict to them. Could you make them public and let us know? Or please, upload the images to any public image server e.g. Imgur.com . Or, at least, copy/paste the error in your comment, please. Otherwise we can't help you without knowing the error :)

Cheers!

Reply
Emad B. Avatar

thanks for your reply and sorry for being late

first image
https://imgur.com/a/TbVIhRC

second image
https://imgur.com/bwqAuYE

Reply

Hey Emad,

I see both images identical :) Anyway, I just double-checked: downloaded the course code and run "composer install" in the start/ directory using PHP 7.3.16 installed - it worked great without any errors. Could you re-download the project and just run "composer install" in start/ directory? Do you have the same error? Can you share the screenshot of it?

It just should work. The error I see on both your screenshots probably related to failed "composer update" operation. If do not do any updates and just run "composer install" - it should work.

I hope this helps!

Cheesr!

Reply
Raed Avatar

Hi all,
I'm enjoying this course so far!
Command "make:user" is not defined.
Did you mean one of these?

i tried to run make:auth
but i got this error Missing package: to use the make:auth command, run: composer require security,
Despite i've already run composer require security

Reply

Hey Raed,

If you don't have "make:user" command but have other commands from MakerBundle like "make:auth", "make:entity", etc. - you probably have an old version MakerBundle that just does not have that command. Try to upgrade maker, you can do it with:

$ composer update symfony/maker-bundle

It should help. If not - let me know what version of MakerBundle you have installed, this command should help with this:

$ composer info symfony/maker-bundle

The 2nd error means that looks like you don't have symfony security package that is required to be able to generate Guard authenticator with "make:auth" command. First, try to do exactly what the command says - install security package with:

$ composer require security

And see what output does it show you. Probably there was some failed installation of it.

Cheers!

Reply
Raed Avatar
Raed Avatar Raed | Victor | posted 3 years ago | edited

Hey @Victor Bocharsky,

Thank you so much for your prompt reply, i did re-update the maker-bundle and
run composer require security but it was not helpful
i got this output:
Cannot autowire service "App\Repository\ArticleRepository": argument "$registry" of method "__construct()" references interface "Symfony\Bridg
e\Doctrine\RegistryInterface" but no such service exists. Try changing the type-hint to "Doctrine\Persistence\ManagerRegistry" instead.

<b>Infos after running composer info symfony/maker-bundle</b>

autoload
psr-4
Symfony\Bundle\MakerBundle\ => src/

requires
doctrine/inflector ^1.2
nikic/php-parser ^4.0
php ^7.1.3
symfony/config ^3.4|^4.0|^5.0
symfony/console ^3.4|^4.0|^5.0
symfony/dependency-injection ^3.4|^4.0|^5.0
symfony/filesystem ^3.4|^4.0|^5.0
symfony/finder ^3.4|^4.0|^5.0
symfony/framework-bundle ^3.4|^4.0|^5.0
symfony/http-kernel ^3.4|^4.0|^5.0

requires (dev)
doctrine/doctrine-bundle ^1.8|^2.0
doctrine/orm ^2.3
friendsofphp/php-cs-fixer ^2.8
friendsoftwig/twigcs ^3.1.2
symfony/http-client ^4.3|^5.0
symfony/phpunit-bridge ^4.3|^5.0
symfony/process ^3.4|^4.0|^5.0
symfony/security-core ^3.4|^4.0|^5.0
symfony/yaml ^3.4|^4.0|^5.0

<b>ArticleRepository class</b>

`namespace App\Repository;

use App\Entity\Article;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Common\Collections\Criteria;
use Symfony\Bridge\Doctrine\RegistryInterface;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;

/**

  • @method Article|null find($id, $lockMode = null, $lockVersion = null)
  • @method Article|null findOneBy(array $criteria, array $orderBy = null)
  • @method Article[] findAll()
  • @method Article[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    */
    class ArticleRepository extends ServiceEntityRepository
    {
    public function __construct(RegistryInterface $registry)
    {
     parent::__construct($registry, Article::class);
    

    }`

I appreciate your help ! Thanks

Reply

Hey Raed,

Well, actually, it helped as far as I see, right? At least, you have a different error now :) So I believe you do have that "make:user" command, run "bin/console make:user --help" to make sure it is available. Or just "bin/console make:" one and look it in the list of available commands from Maker bundle.

About another error you see - looks like you upgraded too much, I suppose you did "composer update"? If so, it looks like it upgraded not only the Maker bundle but all your packages, including Doctrine package. Basically, you need to do what the error message suggest you, change typehint from "RegistryInterface" to "ManagerRegistry" in your "ArticleRepository" (and probably in other entity repositories too).

I hope this helps!

Cheers!

Reply
Raed Avatar
Raed Avatar Raed | Victor | posted 3 years ago | edited

Hey victor ,

Thanks a lot for your reply & help !

Yes it helped so much that we could kill the first error successfully :-)

- looks like you upgraded too much, YES ,i thought upgrading would help me solve the problem, afterwards, i did change typehint from "RegistryInterface" to "ManagerRegistry" only in "ArticleRepository" ignoring that i should have also changed it in all other repositories,
finally, i re-started the project with only installing the composer, and no error showed after.
I'm glad that i made this type of error :-) Because you just uncovered a lot behind the scene ! Thanks again !

Reply

Hey Raed,

Haha, glad you got it working :) Yeah, it depends on project but sometimes you need to do some minor tweaks after packages upgrade, and fixing errors step by step should help moving forward.

Cheers!

Reply
Nathan Avatar
Nathan Avatar Nathan | posted 3 years ago | edited

Hi,

I'm trying to set up the starting code of this lesson to follow along by following the steps in the ReadMe.

Everything goes without a problem, until i try to execute bin/console doctrine:fixtures:load.

Then I get this notice: Notice: Trying to access array offset on value of type null. This prevents the fixtures from being loaded.

Any idea why this is happening?

Thanks

Reply

Hey Nathan

Looks like you got outdated code, can you re-download it and try again? if you will get same notice again, than share please your php and doctrine/orm versions

Cheers!

Reply

Ok, I've coded along since the first episode of this course. I did not know how to best start a new project so I started a new branch and copied all the files from the source code to that branch. I don't know if this is the best way to do this.

When installing everything ran rather smooth until I tried to run the server and I get this huge error:

Exception thrown when handling an exception (Symfony\Component\Config\Exception\FileLoaderLoadException: Unable to find file "@FrameworkBundle/Resources/config/routing/errors.xml" in @FrameworkBundle/Resources/config/routing/errors.xml (which is being imported from "C:\Bitnami\wampstack-7.3.11-0\apache2\htdocs\the_spacebar\config\routes\dev\framework.yaml"). Make sure the "FrameworkBundle/Resources/config/routing/errors.xml" bundle is correctly registered and loaded in the application kernel class. If the bundle is registered, make sure the bundle path "@FrameworkBundle/Resources/config/routing/errors.xml" is not empty.)

I tried looking into the config files but I am rather confused about where to find this certain config

Reply

Hey juantreses

Let me see if I got it right. You copied all the files from the start directory to a new folder in your system? Then, you ran composer install without any problems until you ran php bin/console server:run?

If that's the case, I think something went wrong during the process. Try clearing the cache manually and re-install your vendors
I hope it does the job but if not, please let me know

Cheers!

Reply

So, it appears I was confusing a branch and a worktree in git workflow. So I started over in a new directory and everything is working fine now.

Now my question is: How can I get these two different directories on the same repository but a different working tree?

Reply

you could create a branch per each directory

Reply
Heninstoa Avatar
Heninstoa Avatar Heninstoa | posted 3 years ago

Hi,I have already downloaded the courses,and while installing it.After composer install.I have got this error.

In ContainerBuilder.php line 1062:

Circular reference detected for service "nexy_slack.client", path: "nexy_slack.client -> Nexy\Slack\Client -> nexy_slack.client".

Can someone help me please

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.1.3",
        "ext-iconv": "*",
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "knplabs/knp-markdown-bundle": "^1.7", // 1.7.0
        "knplabs/knp-paginator-bundle": "^2.7", // v2.8.0
        "knplabs/knp-time-bundle": "^1.8", // 1.8.0
        "nexylan/slack-bundle": "^2.0,<2.2.0", // v2.0.0
        "php-http/guzzle6-adapter": "^1.1", // v1.1.1
        "sensio/framework-extra-bundle": "^5.1", // v5.2.0
        "stof/doctrine-extensions-bundle": "^1.3", // v1.3.0
        "symfony/asset": "^4.0", // v4.1.4
        "symfony/console": "^4.0", // v4.1.4
        "symfony/flex": "^1.0", // v1.17.6
        "symfony/framework-bundle": "^4.0", // v4.1.4
        "symfony/lts": "^4@dev", // dev-master
        "symfony/orm-pack": "^1.0", // v1.0.6
        "symfony/security-bundle": "^4.0", // v4.1.4
        "symfony/serializer-pack": "^1.0", // v1.0.1
        "symfony/twig-bundle": "^4.0", // v4.1.4
        "symfony/web-server-bundle": "^4.0", // v4.1.4
        "symfony/yaml": "^4.0", // v4.1.4
        "twig/extensions": "^1.5" // v1.5.2
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.0", // 3.0.2
        "easycorp/easy-log-handler": "^1.0.2", // v1.0.7
        "fzaninotto/faker": "^1.7", // v1.8.0
        "symfony/debug-bundle": "^3.3|^4.0", // v4.1.4
        "symfony/dotenv": "^4.0", // v4.1.4
        "symfony/maker-bundle": "^1.0", // v1.7.0
        "symfony/monolog-bundle": "^3.0", // v3.3.0
        "symfony/phpunit-bridge": "^3.3|^4.0", // v4.1.4
        "symfony/profiler-pack": "^1.0", // v1.0.3
        "symfony/var-dumper": "^3.3|^4.0" // v4.1.4
    }
}
userVoice