To setup a WAMP environment (a web server of Apache, PHP, MySQL in Windows platform), you can install the packages one by one manually, or choose a much easier way: install WampServer.
WampServer is a Windows web development environment. It allows you to
create web applications with Apache2, PHP and a MySQL database.
Alongside, PhpMyAdmin allows you to manage easily your databases.
WampServer installs automatically all you need to start developing web
applications and is very intuitive to use. You will be able to tune your
server without even touching the setting files.
Go to the WampServer site to download: WampServer Site
Note:
You might encounter with error "Missing MSVCR100.DLL or MSVCR110.DLL" during the installation of WampServer. It means you need to install Microsoft C/C++ Redistributable runtime libraries. It is available from Microsoft website. The detailed solution is provided here: Missing MSVCRxxx.DLL Thread.
Restart computer after intallation completed. Now I have Apache, PHP, MySQL installed.
Start WampServer: Start --> All Apps --> WampServer --> start WampServer
Try the Web server at a browser with "localhost", or find and click on the WampServer icon in task bar at right bottom corner --> Localhost. Tada! Your WAMP web server is running!
Now I need to create a symfony project.
Go to your project folder, i.e.
cd C:\wamp\www
Note:
To make less typing and make it easier to run php in command line, you can add the location of php.exe to environment variable PATH. (Control Panel-->System and Security-->System-->Change settings-->Advanced-->Environment Variables-->System variables>Path-->Edit, Add ';C:\wamp\bin\php\php5.5.12' at the end of value. Restart Command Prompt to let the new path take effect.
Install symfony:
..\bin\php\php5.5.12\php.exe -r "readfile('http://symfony.com/installer');" > symfony
Create the project:
..\bin\php\php5.5.12\php.exe new myProject
Wait a while for Symfony to download the packages and prepare the project. When it's done,
cd myProject
..\..\bin\php\php5.5.12\php.exe app\console server:run
Now test the symfony project at browser:
localhost:8000
Thursday, May 21, 2015
Monday, May 04, 2015
[Symfony] Database and Doctrine (2) - Entity Relationships
Entity Relationships/Associations
Creating the Category entity. Let Doctrine create the class for you.
$ php app/console doctrine:generate:entity \
--entity="AppBundle:Category" \
--fields="name:string(255)"
--entity="AppBundle:Category" \
--fields="name:string(255)"
Relationship Mapping Metadata
To relate the Category and Product entities, start by creating a products property on the Category class.
# src/AppBundle/Resources/config/doctrine/Category.orm.yml
AppBundle\Entity\Category: type: entity # ... oneToMany: products: targetEntity: Product mappedBy: category # don't forget to init the collection in the Category::__construct() method
# $this->products = new ArrayCollection();
# of the entity |
First,
since a Category object will relate to many Product objects, a products
array property is added to hold those Product objects. This
isn't done because Doctrine needs it, but because it makes sense
in the application for each Category to hold an array of Product
objects.
// src/AppBundle/Entity/Category.php
use Doctrine\Common\Collections\ArrayCollection;
class Category
{
// ...
/**
* @ORM\OneToMany(targetEntity="Product", mappedBy="category")
*/
protected $products;
public function __construct()
{
$this->products = new ArrayCollection();
}
}
Next,
since each Product class can relate to exactly one Category object,
you'll want to add a $category property to the Product class:
// src/AppBundle/Entity/Product.php
class Product
{
// ...
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="products")
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
protected $category;
}
Finally, tell Doctrine to generate the missing getter and setter methods of the added new property in both the Category and Product
classes:
$ php app/console doctrine:generate:entities AppBundle
Before
you continue, be sure to tell Doctrine to add the new category table,
and product.category_id column, and new foreign key:
$ php app/console doctrine:schema:update --forceSaving Related Entities
use AppBundle\Entity\Category;
use AppBundle\Entity\Product;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller
{
public function createProductAction()
{
$category = new Category();
//set category data
use AppBundle\Entity\Product;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller
{
public function createProductAction()
{
$category = new Category();
//set category data
$product = new Product();
// Set product data
// Set product data
// relate this product to the category
$product->setCategory($category);
$em = $this->getDoctrine()->getManager();
$em->persist($category);
$em->persist($product);
$em->flush();
return new Response(
'Created product id: '.$product->getId()
.' and category id: '.$category->getId()
);
}
}
$product->setCategory($category);
$em = $this->getDoctrine()->getManager();
$em->persist($category);
$em->persist($product);
$em->flush();
return new Response(
'Created product id: '.$product->getId()
.' and category id: '.$category->getId()
);
}
}
Now, a single row is added to both the category and product tables. The product.category_id column for the new product is set to whatever the id is of the new category. Doctrine manages the persistence of this relationship for you.
Fetching Related Objects
public function showAction($id)
{
$product = $this->getDoctrine()
->getRepository('AppBundle:Product')
->find($id);
$categoryName = $product->getCategory()->getName();
// ...
}
When you call $product->getCategory()->getName(), Doctrine silently makes a second query to find the Category that's related to this Product. It prepares the $category object and returns it to you.
You can also query in the other direction:
public function showProductsAction($id)
{
$category = $this->getDoctrine()
->getRepository('AppBundle:Category')
->find($id);
$products = $category->getProducts();
// ...
}
{
$category = $this->getDoctrine()
->getRepository('AppBundle:Category')
->find($id);
$products = $category->getProducts();
// ...
}
Joining Related Records
You can avoid the second query by issuing a join in the original query. Add the following method to the ProductRepository class:
// src/AppBundle/Entity/ProductRepository.php
public function findOneByIdJoinedToCategory($id)
{
$query = $this->getEntityManager()
->createQuery(
'SELECT p, c FROM AppBundle:Product p
JOIN p.category c
WHERE p.id = :id'
)->setParameter('id', $id);
try {
return $query->getSingleResult();
} catch (\Doctrine\ORM\NoResultException $e) {
return null;
}
}
Lifecycle Callbacks
Sometimes, you need to perform an action right before or after an entity is inserted, updated, or deleted. These types of actions are known as "lifecycle" callbacks.
# src/AppBundle/Resources/config/doctrine/Product.orm.yml
AppBundle\Entity\Product:
type: entity
# ...
lifecycleCallbacks:
prePersist: [setCreatedAtValue]
====================================
// src/AppBundle/Entity/Product.php
/**
* @ORM\PrePersist
*/
public function setCreatedAtValue()
{
$this->createdAt = new \DateTime();
}
Reference
Symfony Doctrine
[Symfony] Database and Doctrine (1) - DB, Entity, Repository
First, we can link up the database by configuring app/config/parameters.yml: change the database name, user and password to reflect your own choices.
If your database doesn't exists:
Create database:
$php app/console doctrine:database:create
We are going to create an Entity called Page with text and body:
php app/console doctrine:generate:entity --entity=AppBundle:Page \
--format=annotation --fields="title:string(255) body:text" \
--no-interaction
--format=annotation --fields="title:string(255) body:text" \
--no-interaction
php app/console doctrine:database:create
php app/console doctrine:schema:create
php app/console doctrine:schema:create
Doctrine can automatically create all the database tables needed for every known entity in your application. To do this, run:
$php app/console doctrine:schema:update --force
If you already have database, import it:
- import database ( mysql <import.sql )
- import these database structures into Symfony:
$php app/console doctrine:mapping:import AppBundle yml
The database mapping is created in src/AppBundle/Resources/config/doctrine/
Now we need the form for that entity, another generator command :
php app/console doctrine:generate:form AppBundle:Page --no-interaction
Doctrine Mapping Types
- string: Type that maps a SQL VARCHAR to a PHP string.
- integer: Type that maps a SQL INT to a PHP integer.
- smallint: Type that maps a database SMALLINT to a PHP integer.
- bigint: Type that maps a database BIGINT to a PHP string.
- boolean: Type that maps a SQL boolean or equivalent (TINYINT) to a PHP boolean.
- decimal: Type that maps a SQL DECIMAL to a PHP string.
- date: Type that maps a SQL DATETIME to a PHP DateTime object.
- time: Type that maps a SQL TIME to a PHP DateTime object.
- datetime: Type that maps a SQL DATETIME/TIMESTAMP to a PHP DateTime object.
- datetimetz: Type that maps a SQL DATETIME/TIMESTAMP to a PHP DateTime object with timezone.
- text: Type that maps a SQL CLOB to a PHP string.
- object: Type that maps a SQL CLOB to a PHP object using serialize() and unserialize()
- array: Type that maps a SQL CLOB to a PHP array using serialize() and unserialize()
- simple_array: Type that maps a SQL CLOB to a PHP array using implode() and explode(), with a comma as delimiter. IMPORTANT Only use this type if you are sure that your values cannot contain a ”,”.
- json_array: Type that maps a SQL CLOB to a PHP array using json_encode() and json_decode()
- float: Type that maps a SQL Float (Double Precision) to a PHP double. IMPORTANT: Works only with locale settings that use decimal points as separator.
- guid: Type that maps a database GUID/UUID to a PHP string. Defaults to varchar but uses a specific type if the platform supports it.
- blob: Type that maps a SQL BLOB to a PHP resource stream
Generating Getters and Setters
# generates all entities of bundles in the AppBundle namespace
$ php app/console doctrine:generate:entities --path="src/" AppBundle
$ php app/console doctrine:generate:entities AppBundle/Entity/Product
Entity files are created in src/AppBundle/Entity/.
Persisting an object to DB:
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();
Fetching object from DB:
$product = $this->getDoctrine()
->getRepository('AppBundle:Product')
->find($id);
// dynamic method names to find based on a column value
$product = $repository->findOneById($id);
$product = $repository->findOneByName('foo');
// find *all* products
$products = $repository->findAll();
// find a group of products based on an arbitrary column value
$products = $repository->findByPrice(19.99);
// query for one product matching by name and price
$product = $repository->findOneBy(
array('name' => 'foo', 'price' => 19.99)
);
// query for all products matching the name, ordered by price
$products = $repository->findBy(
array('name' => 'foo'),
array('price' => 'ASC')
);
if (!$product) {
throw $this->createNotFoundException(
'No product found for id '.$id
);
}
Updating an object
$em = $this->getDoctrine()->getManager();
$product = $em->getRepository('AppBundle:Product')->find($id);
if (!$product) {
throw $this->createNotFoundException(
'No product found for id '.$id
);
}
$product->setName('New product name!');
$em->flush();
Delete an object:
$em->remove($product);
$em->flush();
Doctrine’s Query Builder:
$repository = $this->getDoctrine()
->getRepository('AppBundle:Product');
$query = $repository->createQueryBuilder('p')
->where('p.price > :price')
->setParameter('price', '19.99')
->orderBy('p.price', 'ASC')
->getQuery();
$products = $query->getResult();
$product = $query->getSingleResult();
$product = $query->getOneOrNullResult();
DQL:
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
'SELECT p
FROM AppBundle:Product p
WHERE p.price > :price
ORDER BY p.price ASC'
)->setParameter('price', '19.99');
$products = $query->getResult();
Custom Repository Classes
To create a repository to hold all the customized database manipulation methods, you need to:
- Add the name of the repository class to your mapping definition. (located at src/AppBundle/Resources/config/doctrine/*.orm.yml)
For AppBundle\Entity\Product:
type: entity
repositoryClass: AppBundle\Entity\ProductRepository
table: product
fields:
id:...
Doctrine can generate the repository class for you by running the same command used earlier to generate the missing getter and setter methods:
php app/console doctrine:generate:entities --path="src/" AppBundle
You will notice a new ProductRepository.php file is created under src/AppBundle/Entity.
- Create all necessary functions to provide required database manipulation capabilities (like retrieving data).
Reference
Symfony Doctrine
Subscribe to:
Posts (Atom)