SunshinePHP, Feb 7th 2013 © David Buchmann, Liip AG
David is a senior developper at Liip SA, specializing in Symfony2. He happens to also be a certified Scrum Master and sometimes enjoys doing the scrum master or product owner role for a project.
Liip is doing custom web development with PHP in Switzerland.
$ curl -s https://getcomposer.org/installer | php
$ php composer.phar create-project symfony/framework-standard-edition my-project 2.1.x-dev
Edit composer.json extra section:
"extra": {
"symfony-app-dir": "app",
"symfony-web-dir": "web",
"symfony-assets-install": "symlink"
}
Configure your web server to point to web subfolder of my-project
$ php app/console generate:bundle --namespace=Sunshine/HelloBundle --format=yml
# simply accept all defaults, they are fine
This creates code and adds our bundle to the Kernel
// app/AppKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new Sunshine\HelloBundle\SunshineHelloBundle(),
);
// ...
return $bundles;
}
And also links the routing file in app/config/routing.yml
# src/Sunshine/HelloBundle/Resources/config/routing.yml
sunshine_hello_homepage:
pattern: /sunshine/{name}
defaults: { _controller: SunshineHelloBundle:Hello:index }
namespace Sunshine\HelloBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
class HelloController
{
public function indexAction($name)
{
return new Response("Hello $name");
}
}
<!DOCTYPE html>
<html>
<head>
<title>Welcome to SunshinePHP!</title>
</head>
<body>
<h1>Hello: {{ name }}</h1>
</body>
</html>
namespace Acme\HelloBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
class HelloController
{
public function indexAction($name)
{
return $this->render(
'SunshineHelloBundle:Hello:index.html.twig',
array('name' => $name)
);
}
}
<?php
namespace Sunshine\HelloBundle\Entity;
class Page
{
private $mainText;
public function __construct($text)
{
$this->mainText = $text;
}
public function getMainText()
{
return $this->mainText;
}
public function setMainText($text)
{
$this->mainText = $text;
}
}
$page = new \Sunshine\HelloBundle\Entity\Page('test');
return $this->render(
'SunshineHelloBundle:Default:index.html.twig',
array('name' => $name, 'page' => $page)
);
<p>{{ page.mainText }}</p>
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Page
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="main_text", type="string")
*/
private $mainText;
...
$ app/console doctrine:schema:update --dump-sql
CREATE TABLE Page (id INTEGER NOT NULL, main_text VARCHAR(255) NOT NULL, PRIMARY KEY(id))
$ app/console doctrine:schema:update --force
Updating database schema...
Database schema updated successfully! "1" queries were executed
$ app/console doctrine:schema:drop --dump-sql
DROP TABLE Page
# --force would actually drop it
public function createAction()
{
$page = new Page('SunshinePHP in sunny florida');
$em = $this->getDoctrine()->getManager();
$em->persist($page);
$em->flush();
return new Response('Created page id '.$page->getId());
}
sunshine_hello_create:
pattern: /sunshine-create
defaults: { _controller: SunshineHelloBundle:Default:create }
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$repository = $em->getRepository('SunshineHelloBundle:Page')
$page = $repository->find($id);
if (! $page) {
throw new NotFoundHttpException("no page $id");
}
// render as before
}
sunshine_hello_show:
pattern: /sunshine-show/{id}
defaults: { _controller: SunshineHelloBundle:Default:show }
public function createAction(Request $request)
{
$page = new Page('');
$form = $this->createFormBuilder($page)
->add('mainText', 'textarea')
->getForm();
return $this->render(
'SunshineHelloBundle:Default:form.html.twig',
array('form' => $form->createView()));
}
<form action="{{ path('sunshine_hello_create') }}"
method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<input type="submit" />
</form>
// create form, then
if ($request->isMethod('POST')) {
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($page);
$em->flush();
$showUrl = $this->generateUrl(
'sunshine_hello_show',
array('id' => $page->getId())
);
return $this->redirect($showUrl);
}
}
php composer.phar require "knplabs/knp-markdown-bundle:1.2.*@dev"
$bundles = array(
// ...
new Knp\Bundle\MarkdownBundle\KnpMarkdownBundle(),
);
{{ page.mainText|markdown }}
If you can do chmod +a:
$ rm -rf app/cache/*
$ rm -rf app/logs/*
$ sudo chmod +a "www-data allow delete,write,append,file_inherit,directory_inherit" app/cache app/logs
$ sudo chmod +a "`whoami` allow delete,write,append,file_inherit,directory_inherit" app/cache app/logs
Otherwise set up ACL and:
$ sudo setfacl -R -m u:www-data:rwx -m u:`whoami`:rwx app/cache app/logs
$ sudo setfacl -dR -m u:www-data:rwx -m u:`whoami`:rwx app/cache app/logs
class MyClass
{
public function do()
{
global $variable;
echo $variable;
}
}
NO!
class MyClass
{
public function do()
{
echo Registry::instance()->get('variable');
}
}
Meh. A bit better but not good.
class MyClass
{
private $variable;
public function __construct($variable)
{
$this->variable = $variable;
}
public function do()
{
echo $this->variable;
}
}
This is dependency injection!