How to build a login-registration system using Symfony – A PHP Framework – Part 2

Hello again,

In the last tutorial we saw a very basic implementation which will simply print “Hello World” on your browser screen. For those who have landed up here straight here, you may want to go through this blog post. Getting started with Symfony – A PHP Framework – Part 1 By now if you have decided to go ahead with symfony and use it for your site development, this is what you will be looking for next.

You can download the code for this tutorial from google code base.

svn checkout http://abhinavsingh.googlecode.com/svn/trunk/PHP/
Frameworks/Symfony/Authentication abhinavsingh-read-only

A Registration-Login-Logout System for your site
This is mostly the first thing you end up building for your site. To be frank, I myself haven’t made this application. I will make it as I write this blog, and note down all my steps here, so that I don’t miss any detail.

  1. We will name our project as Authentication
  2. Create a folder called Authentication under the Symfony directory we made in the last tutorial. For me its here C:WorkspaceSymfonyAuthentication
  3. Open your command line and point it to the above created folder
  4. Type “symfony init-project Authentication” and it will create same directory structure that we discussed in last tutotial.
  5. Lets create an application inside this, we will name it as Auth
  6. Type “symfony init-app Auth” and it will create an application named Auth under the apps folder. (C:WorkspaceSymfonyAuthenticationappsAuth)
  7. First we need a module called Registration, to allow our users to register.
  8. Type “symfony init-module Auth Registration” and it will tell symfony to create a module named Registration inside our application Auth
  9. As told in last tutorial copy the C:php5peardatasymfonywebsf folder to C:WorkspaceSymfonyAuthenticationwebsf. At the end of this part, we will learn how can we skip this copying again and again
  10. Open C:WorkspaceSymfonyAuthenticationappsAuthmodulesRegistrationactionsactions.class.php and comment out the forwarding as discussed in last tutorial.
  11. Go to your command line and type “symfony clear-cache“. Read why we do this in the last tutorial.
  12. Open http://localhost/Symfony/Authentication/web/ in your browser and you must get something like this.


Figure 1

OOPS! Did we missed something? Yes we did and intentionally. We could have gone to C:WorkspaceSymfonyAuthenticationappsAuthconfigrouting.yml and redirected our Authentication application to our Registration Module by default. In that case we would have seen an empty page since indexSuccess.php file inside C:WorkspaceSymfonyAuthenticationappsAuthmodulesRegistrationtemplates is empty. But since we didn’t modified the routing.yml file, it took us to the default module of symfony.

So how do we access our Registration module without modifying routing.yml file??
http://localhost/Symfony/Authentication/web/Registration/index is the answer 🙂

As a convention
http://localhost/Symfony/Authentication/web/<Module>/<ModuleFile>
this is the standard for symfony.

Hence it went to Registration module and then indexSuccess.php page inside that. Cool so we actually just followed up from our last tutorial till here. Lets now do the actual development.

Defining a layout for our website
Before we do any backend stuff, lets atleast get our site out of that blank page (http://localhost/Symfony/Authentication/web/Registration/index). However, If you view the source of that blank page, you will actually find that there are already some header, css, body tags in the source code. How is this coming? when we have an empty indexSuccess.php file.

From our last tutorial we saw the flow which symfony follows to finally display a page on the browser. But then I actually skipped a step to ease down the tutorial. In symfony we follow the Decorator Design Patterns (I hope i m not wrong here) , to get the front end stuff. Essentially Decorator Design Pattern consists of a Layout and a Content page.

In symfony our layout file is located under at C:WorkspaceSymfonyAuthenticationappsAuthtemplateslayout.php. Open it up and you will know the answer to “How are those meta tags, head tags and body tags coming”.

Cool enough. Lets go back to our indexSuccess.php file of Registration module and design our website. With a little CSS and HTML, I came up with this design page for our site. Mostly inspired and stolen from my new site Gtalkbots.com


Figure 2

We will shift a bit of code from this page to our layout.php page later on so that we need now write the same modules again and again. Download all the code, from the my google code vault location given at the beginning and end of this tutorial.

Designing the backend database:
Now we need  a databases schema which will save our registered user’s data.  Lets create our database structure.

As talked about in last tutorial, symfony follows ORM programming technique. For this, they provide a method through which you actually need not go to your database and create tables. Symfony will do that for you. Not only this, Symfony will also allow you to skip most of the SQL queries. Lets see how.

  1. Open C:WorkspaceSymfonyAuthenticationconfigschema.yml . From extension we know that symfony follows YAML structures which is similar to XML, but a bit easy to write. We will define our table structures in this file.
  2. Type the following in the schema.yml file:
    Propel:
      users:
        id:        { type: integer, primaryKey: true, autoIncrement: true }
        username:  varchar(100)
        emailid:   varchar(100)
        password:  varchar(100)
    
  3. Note the indentation, it is very very important when you are using YAML. Indentation actually decides how the YAML parsers will read and interpret the information you want to write in .yml files. In our case we have a very simple schema.yml file having only one table. We will learn about what that “Propel” is all about later, but lets focus from line 2.
  4. We are trying to make a table called users having fields like id, username, emailid and password
  5. Now before Symfony makes this table for you, we need to tell symfony the database username and password. For this we have a configuration file called propel.ini, located at C:WorkspaceSymfonyyahooconfigpropel.ini
  6. Open it and change the lines as below:
    propel.database.createUrl  = mysql://root@localhost/
    propel.database.url        = mysql://root:password@localhost/authentication
    

    Now go to your mysql database and create a database named authentication, which symfony will use from now on.

  7. Type “symfony propel-build-all” in your command line. This command will happily create a table named “users” in youy MySQL database “authentication”. Some of the possible errors which I got in the past are:
    • Your PHP must be compiled with XSLT, hence enable it by going in your php.ini file
    • In schema.yml file never use TABS. The YAML parsers don’t understand TABS. User SPACES intead of that.
  8. To cross verify check your database, if the table has been created. Now a bit about Propel.

Propel is nothing but a third-party-vendor plugin which Symfony use. It helps in parsing the YAML files, creating and executing the whole ORM module including parsing of schema.yml , creating tables, creating ORM data objects. We will slowly and gradually learn a lot more about ORM.

A look at the model layer
Another thing which the propel command did was, it created the whole ORM module. If you go to C:WorkspaceSymfonyAuthenticationlibmodel you can see 2 folders being created and a few files too.

For every table, propel build 5 files under the model folder. These files are basically the class files, which will provide use with a database object which we can use to select or insert data in the database.

C:WorkspaceSymfonyAuthenticationlibmodelomBaseUsers.php &
C:WorkspaceSymfonyAuthenticationlibmodelomBaseUsersPeer.php are the only 2 files which will be re-created when you run the propel command again.

The file positioned at
C:WorkspaceSymfonyAuthenticationlibmodelUsers.php &
C:WorkspaceSymfonyAuthenticationlibmodelUsersPeer.php will be as it is from this point in time. If you write your own methods in them, they will remain as it is even when you re-create your database schema.

We will use these created ORM files to insert, delete, select data from the databases. In symfony we can actually skip writing a SQL query (though we can always write a direct query too)

Writing the backend Code:
With UI and database in shape, its time to write our backend code which will handle the registration form submission. If you notice the source code of our form, the action field is set as :

<form id=”registration” action=”<?php echo url_for(“Registration/index”); ?>” method=”POST”>

In symfony we have a lot of helper functions which we can use. In this case we users url_for helper function, which helps in generating a url with <module>/<modulefile> being passed as parameter.

So we have our form being submitted to indexSuccess.php itself, i.e. SELF.
Hence lets go to executeIndex() method in action.class.php and write the code which will handle the submitted form.

Copy the modified action.class.php file from the vault location. I have documented every line inside the code, which will walk you through the code. Understand the flow and continue reading.

However before we insert any data in the database, we need to give the database parameters. Go to
C:WorkspaceSymfonyAuthenticationconfigdatabases.yml
and uncomment the lines of code in there. Finally it should be of the following structure:

all:
  propel:
    class:          sfPropelDatabase
    param:
      dsn:          mysql://root:password@localhost/authentication

Lastly open:
C:WorkspaceSymfonyAuthenticationappsAuthconfigsettings.yml
and go to the last line of the file. You will find
# compat_10    off
being commented out
Uncomment it and then turn on compat_10 i.e.
compat_10    on

Clear your cache, before submitting the form (symfony clear-cache) and then try to register.

If you have followed everything, you will be able to successfully able to register and visit mainSuccess.php of the module.

I have documented all the code which you can download from the vault location. Read it, try it, play with it.

PS: The best documentation is available at symfony-project website. This tutorial was intended to
build a real life scenario application using Symfony. Though I must admit that I still haven’t used 100% possible symfony
for this application, just to make it simple but still give you a feel of how things flow in symfony.

Leave a comment if you have any doubt or difficulty in implementing the code.
Do leave a comment even if you like the code 😉

  • CodeGuru

    Excellent tutorial. Your code vault zipped file just worked like anything. Looking forward to more implementation examples.

  • JD001

    Thanks for this shit. You took a load off from me by posting the codes 🙂

  • Thanks. Keep tuned, in my next few post I will be posting some more code snippets (file upload, upload meter, etc etc)

    That might take more off you 😉

  • Sowmya

    keep up the good work 🙂

  • Janakiraman

    Really a nice one and helped me a lot.. Thanks for the stuff….

  • Janakiraman

    I have worked as said above but i have got a problem. When i try to save the data to the database it throws me a exception saying that

    “throw new PropelException(“No connection params set for ” . $name);”

    Please help me in sorting out..

    I am using sandbox.

  • Hi Janakiraman,

    Well this is one of the problem with symfony actually (infact with YAML)

    In YAML files you should never use TABS but SPACEBAR to move around.

    I have myself faced this a couple of times, and frankly speaking I couldn’t read to a solution. Only thing I could do then was:

    1. Take a backup of my current project template and action files.
    2. Create a fresh project and use my files from previous project.
    3. Do not use previous project .yml files, since there is where the problem lies.
    4. Rewrite the YAML files again, and if you are lucky, You will hit the Bull’s eye.

    Why not download the whole copy of the tutorial from my code vault and try running that once?

    Also are you trying this on windows?? I had this problem only on windows till now.

    PS: YAML is the problem here, Use a good editor. I use SciTe on windows:
    http://www.scintilla.org/SciTE.html

    Hopefully this helps 🙂

  • Leek Adam

    Nice tutorial again Abhi. I am really glued to your blog. Keep them coming.

  • Janakiraman

    hi thanks for your quick response.

    Please tell me which version of symfony you are using?

    Will this work with symfony version 1.0.18

    I am able to create the table in the database, using “symfony propel-build-all” but when trying to save i get the same error as mentioned below.

    No connection params set for Propel

    if ($dsn === null) {
    throw new PropelException(“No connection params set for ” . $name);
    }

    I also checked the yml files also.

    I also tried with symfony1.1 their also i get the same error.

    Please help me out, i am newbie to symfony.

    I trying this past three days. But i could not trace out my error.

  • Hi,

    Sad to know you are unable to get through. Doing a

    cmd> symfony -V , gives me
    symfony version 1.1.2 (C:PHPPEARsymfony)

    Also did you tried the following:
    1. Create a new project for yourself and try everything there again.
    2. Download the code base from code.google.com and tried running that http://abhinavsingh.googlecode.com/files/svn-trunk-PHP-Framework-Symfony-Authentication.rar

    Well I too have faced this problem 2-3 times and recreating the symfony project always help me. Though I haven’t faced this problem on Linux.

    Also see if the initial 3-5 links here helps you. http://www.google.co.in/search?hl=en&q=No+connection+params+set+for+&btnG=Google+Search&meta=

    I am sure this time you will be able to crack through 😉

  • Pingback: rpsblog.com » A week of symfony #96 (27 october -> 2 november 2008)()

  • aah, missed out towards the end 🙁 I am not sure if symbolic link will help, but correct way is by setting up a virtual host:

    <VirtualHost *:80>
    ServerName myapp.example.com
    DocumentRoot “/home/steve/myproject/web”
    DirectoryIndex index.php
    Alias /sf /$sf_symfony_data_dir/web/sf
    <Directory “/$sf_symfony_data_dir/web/sf”>
    AllowOverride All
    Allow from All
    </Directory>
    <Directory “/home/steve/myproject/web”>
    AllowOverride All
    Allow from All
    </Directory>
    </VirtualHost>

    In the configuration in Listing 3-1, the $sf_symfony_data_dir placeholder must be replaced by the actual path. For example, for a PEAR installation in *nix, you should type something like this:

    Alias /sf /usr/local/lib/php/data/symfony/web/sf

    PS: These instructions picked directly from Symfony Project website 🙂

  • Great tutorial. You mentioned a way to avoid copying the sf folder to each project, Did I miss the answer? Is it simply a matter of creating a symbolic link?

  • OOPS all opening closing tags parsed away:

    Refer http://www.symfony-project.org/book/1_1/03-Running-Symfony for more details. Under section Configuring the Web Server.

    I hope this helps.

  • Hi, I follow your tutorial above, but in the end, when I execute “symfony clear-cache” from my terminal, I got error notification;

    Failed to write cache file “/var/www/Symfony/Authentication/cache/Auth/prod/config/config_settings.yml.php” generated from configuration file “config/settings.yml”.

    I don’t know the cause of proble, and I confused, cause I check there is nothing ../Auth/prod directory in my file and your file.

    Btw I use Ubuntu and Symfony 1.1.4

    Thanks a lot

  • Well I haven’t check on my ubuntu yet, but on my windows symfony set up, I do have a folder with this location:

    C:WorkspaceSymfonyAuthenticationcacheAuthprodconfig

    Well I have never encountered this error, but a guess is that it may be because of directory permissions. Can you check the permissions on the cache directory and set the permissions to 0777 in the worst case.

    And a quick google search gives me a few results: Check them out here:
    http://www.google.co.in/search?hl=en&q=Failed+to+write+cache+file+generated+from+configuration+file+%E2%80%9Cconfig%2Fsettings.yml%E2%80%9D&btnG=Google+Search&meta=

    Hope this helps. Do let me know. I will check on my ubuntu system too if required.

    Regards,
    Abhinav

  • Pingback: Symfony model layer tips and tricks - A PHP Framework - Part 3 | Abhi's Weblog()

  • netra1978

    where is the code??????

  • At the very starting of the tutorial I gave the google code repository link. You can checkout the code from there.

    You will need a cvs checkout software like tortoise for checking it out. http://tortoisesvn.tigris.org/

    Do lemme know if there is any problem for you.

  • Anwamane

    Great tutorial, thanks for your effort.
    Just one thing to point at it:

    Propel: <— I took 8 bloody hours to understand that here should be “propel” instead “Propel” :@
    users:
    id: { type: integer, primaryKey: true, autoIncrement: true }
    username: varchar(100)
    emailid: varchar(100)
    password: varchar(100)

  • Abi.. can u pls explain wad this function does!!
    i kinda know wen its called {Registration/main}
    But wads happening in it???

      public function executeMain() {
        $ULI = $this->getRequest()->getCookie(‘ULI’);
        $ULK = $this->getRequest()->getCookie(‘ULK’);

    // Before we allow the user to view this page
    // We need to authenticate user with the database
    $c = new Criteria();
    $c->add(UsersPeer::EMAILID,$ULI);
    $c->add(UsersPeer::PASSWORD,$ULK);
    $userInfo = UsersPeer::doSelect($c);
    if(count($userInfo) != 1) {
     $this->redirect(‘Registration/index?error=authError’);
    }

  • Hey sorry for late response, was off on vacation.

    1. Well the first thing in executeMain() means:
    We try to extract browser cookie’s ULI (corresponds to username) and ULK (corresponds to password).
    2. Second we try to query for username and password in the database table. If the combination exists, user is authenticated. If not we redirect him to the Registration/index?error=authError page.

    I hope this will clear your doubts 😀
  • Hello Abhinavsingh, thanks very much. your instructions are very helpful for me. i make registration module successfully. now i want to make login module, its authentication, and how to manage sessions for profile pages for user and edit profile pages for user, and manage registered user in our website.
    thanks.
    i hope you will clear for my problem.
    thanks.
     

  • well i guess ULK and ULI can help you in all your needs. (cookie way) otherwise you can maintain user sessions too at server side (session way).

    Though i will recommend using ULI and ULK for the same. Simply authenticate user, before submitting his/her profile changes.

  • Hi Vinay,

    I think what you asked through email can be of use to everyone out here. Hence including your mail here and replying the same:

    I am using setCookie(“ULI”,$EmailId); function for set email id in cookie but unfortunately, i cannot set cookie. at next sentence if i use print_r($_COOKIE); for see all cookie then the cookie is not availabe for email id. and i also cannot get value of email id at  $ULI = $this->getRequest()->getCookie(‘ULI’); sentence. whats the problem?”

    My question is:
    What platform are you using to develop your application? Windows or *nix?

    Regards,
    Abhinav

  • Hello Abhi,

    Thanks For Interesting in my problem.
    I want to get Email-id in cookie. basically cookie is not set using
    setCookie()m it is my problem. I am using Winows Xampp Version 1.6.6a .
    Using that Cookie I have to make sure that user is regerested and can auto
    login in system immidiate after registeration and have move to user
    profile page.

    Thank You.

  • Hi Vinay,

    I remember facing difficulty way back, trying setting cookie while working on windows and using http://localhost as the development environment.

    Below is the solution that seems to be working for me over the year now:

    define('COOKIEPATH', preg_replace('|https?://[^/]+|i', '', 'http://localhost/'));
    define('COOKIE_DOMAIN', false);

    and then use this to set your cookie: setcookie($string, $value, $expires, COOKIEPATH, COOKIE_DOMAIN);

    Hope this will help you 😀

  • enim

    hi Abhi!
    im really new to symfony so im really getting every detail from this blog.
    my concern is,  i cant get the code from the vault you’re referring. so i cant understand some of the information especially when you’re talking about the code.
    PLease help. Thnak you.
    regards,
    enim 🙂

  • You need to checkout the code sample from http://abhinavsingh.googlecode.com/svn/trunk/PHP/Frameworks/Symfony/Authentication/ using a SVN client. Alternately you can download them independently but will be time consuming.

    Alternately download this: http://abhinavsingh.googlecode.com/files/svn-trunk-PHP-Framework-Symfony-Authentication.rar and untar it.

    Also let me know the specific area in the code you are having trouble understanding.

  • enim

    Hi again Abhi!
    I have received your rsponse regarding my first post.
    I tried to make my own form and it worked well except that the value for the email variable would not show up. this is the build query:
    http://localhost/Guestbook/web/frontend_dev.php/contact/thankyou/name/asd/amp%3Bemail/asdf
    the “amp%3B” is the culprit. When I removed that from the query and enter. it gets the value.
    Could you tell where it came from?
    the code is exactly like:
    http://www.symfony-project.org/forms/1_1/en/01-Form-Creation
    But I think we use different version
    Please help. Thank you 🙂 – enim
     

  • This is just fine, but a more usefull form will be using the admin-generator capabilities and the sfGuardPlugin posibilities to automatize a lot of work with the Admin generator interface.

  • Pingback: uberVU - social comments()

  • Newbie

    I just changed the case of registration and authentication folders, i.e. Registration to registration
    and
    Authentication to authentication

    The whole application is working file as was mentioned in the blog. At the time of submission url is not getting proper. i changed action of registration form to url_for(“registration/index”); still it is getting a prob in submission.

    even everywhere in action.class.php file I changed the case to mine, still there is a prob in submitting.

    is there any other setting that needs to get changed.
    can you help me.

  • Newbie

    got the solution.
    It was about the p capital of Propel in config file of project and nothing related to case of folder name.

    Thank you for the great tutorial.
    It is a very good option for the newbies like me.

  • Manish

    hello Abhi.. i read your blog and fint it interesting. i am a new bee in Symfony world and i want to learn symfony by my own. i need some help regarding fetching values from database in symfony.can you please help me by giving some example of it.. thanks

  • David

    What is it? Did you what do describe only registration form?

  • Kavitha Sriram

    Explanation is excellent. However I followed the same steps as written here, but still ‘users’ table is not created only the database ‘authentication’ is created in my case. What could be the possible reasons?

  • this infomations seems useless in 2016