So, let's start? Let's write some small but complete project. Scroll to this exactly 1 hour. Suggest a title. Book Shop? If there are no other ideas, then we will write a blog :)
It is assumed that Apache is installed and running on your local machine, as well as PHP at least 5.1.3.
Install symfony
To start quickly, use the sandbox version of Symphony. This is a version that is simply installed, and allows you to immediately start developing using the default project settings. There is another option - to install the Symphony of the bare distribution. In this case, a number of simple actions will be required to deploy the project and some of its configuration. In our case, let's take the path of least resistance. Therefore, download
sf_sandbox_1_2.tgz or
sf_sandbox_1_2.zip and unpack the contents into the root of the project folder. Under Linux, it is recommended to leave the rights to the files that are initially located inside the tar-archive (use the –p key of the tar command). As usual, if something does not work, read the readme file. As a result, we get approximately the following folder structure:
www /
sf_sandbox /
apps /
frontend /
cache /
config /
data /
doc /
lib /
log /
plugins /
test /
web /
css /
images /
js /
')
Here you can see that the
project (project) called
sf_sandbox contains an
application (application) called
frontend . We write in the browser
http: //localhost/sf_sandbox/web/index.php/
and make sure everything works: a page should appear

Also, of course, you can install the Symphony in an arbitrary folder and configure virtual hosts on a web server. Read more about this in the chapters on
symfony installation and the
symfony directory structure of the full-text Symphony Reference.
Create a data model
Blog, comrades, are posts that can be commented on. Accordingly, we need tables in the database where posts and comments will be stored. Since we work in the framework environment, we use its built-in tools to create a model. Make the
schema.yml file and put it in the
sf_sandbox / config / folder. We write the following to this file:
propel:
blog_post:
id: ~
title: {type: varchar (255), required: true}
excerpt: {type: longvarchar}
body: {type: longvarchar}
created_at: ~
blog_comment:
id: ~
blog_post_id: ~
author: {type: varchar (255)}
email: {type: varchar (255)}
body: {type: longvarchar}
created_at: ~
This is a configuration file, and we made it in accordance with the syntax of YAML. It is very simple, and allows you to make XML-like structures using indents. But it is much more readable than the same XML. Just remember one thing: you should use spaces, not tabs, for indentation, otherwise the file parser will stumble. You can read more about YAML in the
configuration chapter .
The above diagram (what is written in the schema.yml file is called the data schema) describes the structure of the two tables that we need in our project. The whole point is that based on this scheme, the
blog_post and
blog_comment classes will be automatically created. But more on that later. Save the file, and in the command line write the following:
$ php symfony propel: build-model
Before you execute this command, make sure that the current folder is the root folder of the project (this is where the symfony file is located, which we will constantly run with parameters).
So, after executing this command, several files with classes will be created in the
sf_sandbox / lib / model / folder. These are classes that reflect the structure of database tables on PHP objects (such reflection is called ORM). “Reflects” in this case means that it will be possible to read / add / change / delete entries in the table by calling some methods of the class corresponding to this table. That is, we call the class method - we write the data to the table. Call another method - delete records (all, or on a specific condition). And all this without writing SQL queries! Just call the methods. There are several implementations of ORM. By default, Symphony works with Propel. These classes are part of the model of our application (read more in the
model chapter).
Files are good, but we need tables in the database! Well, we will convert files into tables by means of the Symphony. By default, the sandbox version of the Symphony is configured so that it works with SQLite, that is, no database initialization is required. Now you need to make sure that SQLite works as expected (for this we look at php.ini and read
PHP documentation ).
By default, the
sf_sandbox project uses a database called
sandbox.db , located in the
sf_sandbox / data / folder.
If you want to use MySQL (do you really want to use MySQL? :)), then you just need to ask Symphony about it:
$ php symfony configure: database "mysql: dbname = symfony_project; host = localhost" root mypassword
Naturally, you need to make sure that the
symfony_project database exists and is accessible to the
root user with the password
mypassword .
Now open
sf_sandbox / config / databases.yml and replace 'phptype' with 'mysql', and write the name of the database there (figure out where, I think).
If you still decide to stop at SQLite, then you will need to change some rights on * nix-systems:
$ chmod 777 data data / sandbox.db
Now run
$ php symfony propel: build-sql
As a result, the file
lib.model.schema.sql will be created in the
sf_sandbox / data / sql / folder. This file contains the SQL query that you can execute to create the tables we need. To fulfill this request, run
$ php symfony propel: insert-sql
Don't get scared if a warning pops up. It should be so. The
propel: insert-sql command deletes the tables before it is created, and of course should warn you that it will save them now.
Since we need the ability to create and edit posts on our blog, we will need several forms. Let's make them from the scheme in a couple of seconds:
$ php symfony propel: build-forms
This command will create class files in the
sf_sandbox / lib / form / folder. These classes are used to generate forms for adding and editing elements (posts and comments in our project).
Forget everything I wrote before. Everything is done with one command:
propel: build-all :)
Making an application
Simplify everything to the limit. We assume that all we need to do with posts and comments is to add (Create), receive (Retrive), update (Update) and delete (Delete). For brevity, these four operations are called CRUD.
Since we are new to the Symphony, we need to quickly get some result, then to conjure it. The easiest way to achieve results is to use the CRUD form generator, which looks at the data scheme and creates the necessary files. Run
$ php symfony propel: generate-module --non-verbose-templates --with-show frontend post BlogPost
$ php symfony propel: generate-module --non-verbose-templates frontend comment BlogComment
$ php symfony cache: clear
When we run
propel: generate-module , we must use the
--non-verbose-templates key. If you want to know what it is for, run the command with the
help key:
$ php symfony help propel: generate-module
So, we get two modules (post and comment) that will manage objects that are implemented by the
BlogPost and
BlogComment classes .
The module in the Symphony is presented in the form of one or several pages of similar purpose. Our new modules are stored in the
sf_sandbox / apps / frontend / modules / folder, and they can even be viewed at:
http: //localhost/sf_sandbox/web/frontend_dev.php/post
http: //localhost/sf_sandbox/web/frontend_dev.php/comment
If you try to add a post right now, then an ambush awaits you. Symphony does not know (yet) how to display the post (object!) In the list. For this you need to show her how it is done. To do this, correct the
BlogPost class (file
lib / model / BlogPost.php ): add the __toString () method to it:
class BlogPost extends BaseBlogPost
{
public function __toString ()
{
return $ this-> getTitle ();
}
}
This method tells PHP (and therefore Symphonies) how to convert an object into a string. Now you can display posts (objects!) List (lines!)
Now a few CSS decorations (
sf_sandbox / web / css / main.css file ):
body td
{
font-family: Arial, Verdana, sans-serif;
font-size: 12px;
}
td {margin: 4px; padding: 4px; }
And voila! You can add posts!

You can read about generators in the chapter
generators , and about the structure (project, application, module) we read in the
structure chapter.
From the links above (links to modules) we see that the name of the executable script, which in the Symphony is called the front controller (front controller), was changed from
index.php to
frontend_dev.php . These two scripts run the same application (frontend) in different environments. Using the
frontend_dev.php script, we launch our application in the development environment, where you can try to play with all sorts of programmer things like debug, logs, etc. A characteristic feature of the fact that we are working in the development environment is a socket in the upper right corner of the page, as well as a configuration subsystem on-the-fly. For this reason, this script runs a bit slower than
index.php , which is the front controller of the working environment optimized for speed. If you want to see what happens in the working environment, replace in the links above
frontend_dev.php / with
index.php / and do not forget to clear the cache (did I say that every development should clean the cache when developing?):
$ php symfony cache: clear
http: //localhost/sf_sandbox/web/index.php/
We read more in chapter
environments .
Editing the main template
It is clear that in order to switch between two modules, we need some kind of site navigation. We will draw it in the main template.
Edit the main template file
sf_sandbox / apps / frontend / templates / layout.php and replace everything inside
<body>
to the following:
<div id = "container" style = "width: 700px; margin: 0 auto; border: 1px solid gray; padding: 10px">
<div id = "navigation" style = "display: inline; float: right">
<ul>
<li> <? php echo link_to ('List of posts', 'post / index')?> </ li>
<li> <? php echo link_to ('List of comments', 'comment / index')?> </ li>
</ ul>
</ div>
<div id = "title">
<h1> <? php echo link_to ('My first symfony project', '@homepage')?> </ h1>
</ div>
<div id = "content" style = "clear: right">
<? php echo $ sf_data-> getRaw ('sf_content')?>
</ div>
</ div>
Since we have only 1 hour to develop, we will not pay attention to the appearance and we will not do well: we will write the styles directly in HTML.
What is the result?

Since we're here, let's replace the page title. Edit the view configuration file (view) of the application (here View is V from the MVC abbreviation): (
sf_sandbox / apps / frontend / config / view.yml , look for the line where the title property is written and change it to something that your fantasy. Here we see a few lines, commented out by the # symbol. If desired, they can be uncommented.
default:
http_metas:
content-type: text / html
metas:
title: The best blog ever
#description: symfony project
#keywords: symfony, project
#language: en
robots: index, follow
The main page should also be replaced with its own. To do this, we will edit the
default module, which is stored in the framework, and not in the folder of your application. It can be rewritten (override) with its own module, which we call
main :
$ php symfony generate: module frontend main
By default, the action (action)
index shows some greeting words. To remove this garbage, open
sf_sandbox / apps / frontend / modules / main / actions / actions.class.php and clear everything contained in the
executeIndex () method:
/ **
* Executes index action
*
* @param sfRequest $ request A request object
* /
public function executeIndex ($ request)
{
}
Edit the
sf_sandbox / apps / frontend / modules / main / templates / indexSuccess.php file to make a more meaningful greeting:
<h1> Welcome to my new blog </ h1>
<p> You are the <? php echo rand (1000,5000); ?> th visitor today. </ p>
Now we have to tell the Symphony what action to launch when the main page is requested. To do this, edit the
sf_sandbox / apps / frontend / config / routing.yml file and change the rules for the homepage as follows:
homepage:
url: /
param: {module: main, action: index}
Check what we conjured:
http: //localhost/sf_sandbox/web/frontend_dev.php/

Well, it already looks like a self-made site. You can even create a test post and attach a test comment to it.
The topic is opened here:
views templates .
Passing data from the action to the template
Well, with a certain skill, everything that we have done up to this point takes very little time. Now we will make the
comment module dependent on the
post module; in other words, we need to output comments under the post.
First we need to make comments available for display in the post output template. In the Symphony, when it is necessary to do something under certain conditions, this is done by means of actions (for example,
comments are made under the condition that the page is opened). Open the
sf_sandbox / apps / frontend / modules / post / actions / actions.class.php file and rewrite the
executeShow () method:
public function executeShow ($ request)
{
$ this-> blog_post = BlogPostPeer :: retrieveByPk ($ request-> getParameter ('id'));
$ this-> forward404Unless ($ this-> blog_post);
$ c = new Criteria ();
$ c-> add (BlogCommentPeer :: BLOG_POST_ID, $ request-> getParameter ('id'));
$ c-> addAscendingOrderByColumn (BlogCommentPeer :: CREATED_AT);
$ this-> comments = BlogCommentPeer :: doSelect ($ c);
}
The
Criteria and -Peer objects are part of the ORM
Propel . These four lines of code will implement the link at the SQL level between
blog_comment comments and
blog_post posts. It remains to correct the post template file:
sf_sandbox / apps / frontend / modules / post / templates / showSuccess.php , add the following lines to the end:
// ...
<? php use_helper ('Text', 'Date')?>
<hr />
<? php if ($ comments):?>
<p> <? php echo count ($ comments)?> comments to this post. </ p>
<? php foreach ($ comments as $ comment):?>
<p> <em> posted by <? php echo $ comment-> getAuthor ()?> on <? php echo format_date ($ comment-> getCreatedAt ())?> </ em> </ p>
<div class = "comment" style = "margin-bottom: 10px;">
<? php echo simple_format_text ($ comment-> getBody ())?>
</ div>
<? php endforeach; ?>
<? php endif; ?>
On this page, we used a wonderful thing called the helpers - this is the PHP code that inserts a certain often used part of the finished HTML page onto the page. Create a comment on your first post and check that it was rendered under the post:
http: //localhost/sf_sandbox/web/frontend_dev.php/post/show? id = 1

So the page should look like, if done correctly.
We read in more detail in the chapter
naming conventions .
Insert into the database records associated with another table.
All this is cool, but so far it is impossible to write a comment so that it is automatically attached to the post we are commenting on. To do this, you now need to go to the comment editing page and select the post to which it is attached, using the drop-down list. Well, something like this:

It would be much better if the comment was attached to the post as something simpler. Well, let's do it!
Edit the sf_sandbox / apps / frontend / modules / post / templates / showSuccess.php template file and add the lines to it:
<? php echo link_to ('Add a comment', 'comment / edit? post_id ='. $ blog_post-> getId ())?>
The
link_to () helper creates a hyperlink to the
edit action of the
comment module, and now comments are attached to the post immediately after writing. At the same time, the choice of a post in the drop-down list on the comment editing page does not disappear anywhere and is still available. I think it would be nice to replace this selector with a hidden-field containing the post ID.
Forms in the Symphony are controlled by classes. Therefore, to correct the form, you need to correct the class, in this case it is the
BlogCommentForm class, it lies in the
sf_sandbox / lib / form / folder:
class BlogCommentForm extends BaseBlogCommentForm
{
/ **
* Configure method, called when the form is instantiated
* /
public function configure ()
{
$ this-> widgetSchema ['blog_post_id'] = new sfWidgetFormInputHidden ();
}
}
Forms in the Symphony read here
Forms Book .
Now we have the fact that the new comment is automatically attached to the post to which it was written:

Now that we have already taught the system to add comments, I would like it to be added to the page of the post that he commented after adding a comment. To do this, you need to fix the
processForm method. We are looking for the following code
sf_sandbox / apps / frontend / modules / comment / actions / actions.class.php :
if ($ request-> isMethod ('post'))
{
$ this-> form-> bind ($ request-> getParameter ('blog_comment'));
if ($ this-> form-> isValid ())
{
$ blog_comment = $ this-> form-> save ();
$ this-> redirect ('comment / edit? id ='. $ blog_comment-> getId ());
}
}
And change the redirect to the following:
$ this-> redirect ('post / show? id ='. $ blog_comment-> getBlogPostId ());
There are two things you should pay attention to: first, to save changes to an object, you just need to call the
save () method in the form object class (the form class is associated with the Propel data model, and therefore it knows how to convert data from Forms in a form suitable for preservation in a DB). Secondly, we make a redirect immediately after saving, so if the user, after saving the form, presses F5 in the browser, the form will not be sent again, and accordingly, the object will not be re-saved. This is a very useful practice!
Well, the introduction is over. Where is the blog ?? We already have a blog. Only he is completely raw.
See in the following series:
- Validation of forms
- Changing the URL for different project modules
- Bringing to mind the public part of the project
- Do admin panel
- Restrict access to admin panel
Part twoDear habravchane, is it worth it to translate the second part of the lesson? Or is it monkey labor?