Symfony2 細節小計1

路由

   # 主路由配置app/config/routing.yml
   # 加載某模塊的annotation路由,如AcmeBundle
   acme:
    resource: @XxxxBundle/Controller  #該級目錄及子目錄annotation都被解析
    type:     annotation    #必選
    prefix: ''  #路由前綴

    
  # annotation配置路由
  # 註解命令中引號必須用雙引號
  # 註解命令必須以 /** 打頭, 註釋以 /* 打頭。   
  /**
   * @Route(
           "/Path/{slug}",
           defaults: {},
           name="",
           requirements: {"_format": "html|rss"}
   );
   * @Method("GET");
   */
   public function indexAction($slug){}
   
   
   # annotation路由參數轉換 功能
   # typehint參數爲一個doctrine實體類,自動查詢匹配路由參數的實體對象
   # 沒有匹配對象則返回404頁
   /**
    * @Route("/{id}", name="admin_post_show")
    */
    public function showAction(Post $post){}
   # 還可明確的設定參數轉換細節
   use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
   * @Route("/comment/{postSlug}/new", name = "comment_new")
   * @ParamConverter("post", options={"mapping": {"postSlug": "slug"}})
   
   app/console debug:router 【routeName】//調試路由
   
   url、 參數相互轉換:
   $params = $this->get('router')->match('/blog/my-blog-post'); //assoc-array, 匹配的路由參數
   $uri    = $this->get('router')->generate('blog_show', array('slug' => 'my-blog-post'), bool $生成絕對地址); //生成url


控制器

return $this->redirectToRoute('hello', array('name' => 'Fabien')); //跳轉
return $this->redirect($this->generateUrl('homepage'), 301); //重定向
return $this->forward('AcmeHelloBundle:Hello:fancy', array $context); //內部action轉發


模型AR查詢:
//管理器插入實體
$em = $this->getDoctrine()->getManager(); 
$em->persist($product);
$em->flush();

//倉庫中獲取實體
$repository = $this->getDoctrine()->getRepository('AppBundle:Product');
$repository->find($id);
$repository->findOneByName('foo');

$repository->findBy(array $filters);
$repository->findOneBy(array $filters);

$repository->findByPrice(19.99);
$repository->findAll();

//更新實體
$em = $this->getDoctrine()->getManager();
$product = $em->getRepository('AppBundle:Product')->find($id);
$product->setName('New product name!');
$em->flush();

//刪除實體
$em->remove($product);
$em->flush();


//調用repository類方法
$repo = $this->getDoctrine()->getRepository();
$result = $repo->倉庫定義的方法();


模型DQL查詢
1DQL查詢構建器:
$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(); //沒有結果不會拋出異常

2純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();


Doctrine

鏈接配置: app/config/parameters.yml
doctrine配置: app/config/config.yml

app/console doctrine:database:create //建立庫(必須先建立好具有建庫權限的帳號)
app/console doctrine:database:drop --force //卸載庫
app/console doctrine:generate:entity 【--entity="AppBundle:Category"】 //建立實體
app/console doctrine:schema:update --force //更新映射,【可建立表】
app/console doctrine:generate:entities 【AppBundle】 //爲bundle生成getter,setter, repo等

 一個bundle只能夠接受一種metadata定義格式(來指定字段類型),表名是可選的,若是省略,將基於entity類的名稱自動肯定。
 受保護的SQL字段(如group和user)
 
基礎查詢方法:
$repo->findOneBy(Array) 
     ->findLatest()
 
 關聯查詢:
 查詢到的關聯對象都是延遲加載
 查詢到的關聯對象都是代理對象(代理類存儲在cache目錄), 除非調用getter方法纔會實際進行查詢
 
 join一次性全查關聯對象:
 $product =  $this->getEntityManager()
                ->createQuery(
                    'SELECT p, c FROM AppBundle:Product p
                    JOIN p.category c
                    WHERE p.id = :id'
                )->setParameter('id', $id)
                ->getSingleResult();
$category = $product->getCategory();


生命週期回調lifecycle callback:
* @ORM\HasLifecycleCallbacks() //實體頭部聲明
 * @ORM\PrePersist //實體內部註冊回調方法並在頭部聲明相似該執行點


TWIG

控制器訪問模板路徑格式:
AcmeDemoBundle:Default:index.html.twig  #模板保存在src/Bundle/Resource/views
default/index.html.twig  #模板保存在app/Resource/views, 最佳實踐推薦模板保存在此處
定界符後須要跟一對空格

app/console twig:lint app/Resources/views【/article/recent_list.html.twig】 //模板語法檢查

{{ article.body|raw }} //關閉輸出轉義
Hello <?php echo $view->escape($name【, 'js'】) ?> //php模板形式的轉義, 默認html上下文, 能夠指定js上下文

全局模板變量:
app.user //當前用戶對象
app.request //當前Request對象
app.session //Session對象
app.environment //當前應用程序的環境(dev,prod等)
app.debug //若是是true說明是調試模式,false則不是。

<a href="{{ path('blog_show', {'slug': 'my-blog-post'}) }}"> //相對地址url, 可經過_format指定請求資源格式
<a href="{{ url('blog_show', {'slug': 'my-blog-post'}) }}"> //絕對地址url

{{ parent() }} //應用父模塊內容

{{ include('article/article_details.html.twig', { 'article': article }) }} //包含模板塊
{{ render(controller('AcmeArticleBundle:Article:recentArticles', { 'max': 3 })) }} //嵌入控制器

異步內容hinclude.js:
{{ render_hinclude(controller('...'), 【{'default': 'default/content.html.twig'}】) }}
{{ render_hinclude(url('...'), 【{'default': 'Loading...'})】) }}

資源連接:
<img src="{{ asset('images/logo.png'【, version='3.0'】【, absolute=true】) }}" alt="Symfony!" /> //version: null, 或未設置則默認版本號,  false則停用版本號
## 給twig拓展本身的過濾器my_filter ##

# 自定義一個拓展類,並在其中輸出my_filter
# 拓展類文件推薦放在xxBundle/Tiwg下
namespace AppBundle\Twig;
class MyExtension extends \Twig_Extension{
	public function getName()
	{
	    return 'my_extension';
	}

	public function getFilters()
	{
	    return array(
	        new \Twig_SimpleFilter(
	            'my_filter',
	            array($this, 'some_operation'),
	            array('is_safe' => array('html'))
	        ),
	    );
	}
        
        public some_operation($content){...}
}

# 編輯app/config/services.yml
# 註冊拓展類爲服務,並tag其爲twig.extension
services:
    xx.twig.my_extension:
        class:     xxBundle\Twig\MyExtension
        public:    false
        tags:
            - { name: twig.extension }

{{ content|my_filter }}  #過濾器使用


靜態文件管理器Assetic

不使用assetic: <script src="{{ asset('js/script.js') }}"></script>

將bundle的靜態文件默認拷貝安裝到web目錄下, 通常用於第三方bundle(沒有用assetic的)的靜態資源安裝
app/console assets:install

//////////////////////////////

使用assetic:
    壓縮、合併靜態文件(dev環境,每一個文件依然獨立;prod或者調試關閉時,文件合併)
    LESS, SASS等等的編譯
    圖片文件優化
    隨意目錄存儲靜態文件
    
#引入一條合併的js, 來源於兩個目錄
    {% javascripts '@AppBundle/Resources/public/js/*' '@AcmeBarBundle/Resources/public/js/form.js' %}
        <script src="{{ asset_url }}"></script>
    {% endjavascripts %}
    
#引入一條合併的css,來源於一個目錄
#css的assetic路徑寫法特殊,@AppBundle會報錯,一個已知的框架錯誤
#cssrewrite過濾器用於修復文件dump後, 圖片相對路徑出錯
    {% stylesheets 'bundles/app/css/*' filter='cssrewrite' %}
        <link rel="stylesheet" href="{{ asset_url }}" />
    {% endstylesheets %}
  
#引入圖片
    {% image '@AppBundle/Resources/public/images/example.jpg' %}
        <img src="{{ asset_url }}" alt="Example" />
    {% endimage %}
    
    
配置文件預約義命名資產
# app/config/config.yml
assetic:
    assets:
        xxxx:
            inputs:
                - '@AppBundle/Resources/public/js/thirdparty/jquery.js'
模板中應用命名資產
    {% javascripts '@xxxx' %}
        <script src="{{ asset_url }}"></script>
    {% endjavascripts %}


靜態資源dump合併
prod環境:
    資源路徑被合併,每次文件更新時,須要手動重建一下新的合併文件
        app/console assetic:dump --env=prod --no-debug
dev環境:
    資源路徑被合併,但沒有生成新文件, 內部控制器動態讀取文件併合並後直接輸出(文件更新當即起效,可是很慢)
    # 若是靜態文件加載過慢,可關閉動態生成:
    # app/config/config_dev.yml #這裏是!!開發環境!!下的配置文件
    assetic:
        use_controller: false 
   而後,手動dump出合併文件(每次文件更新都得dump一下)
       app/console assetic:dump
       app/console assetic:watch #結合參數主動監測文件是否變更而後決定更新


指定dump文件的輸出路徑
{% javascripts '@AppBundle/Resources/public/js/*' output='js/compiled/main.js' %}
    <script src="{{ asset_url }}"></script>
{% endjavascripts %}


靜態文件壓縮(UglifyJS和UglifyCSS

全局安裝壓縮組件
cnpm install -g uglify-js
cnpm install -g uglifycss

配置壓縮組件可用:
# app/config/config.yml
assetic:
    node: /usr/bin/nodejs    #可選, 手動指定node路徑
    filters:
        uglifyjs2:
            bin: /usr/local/bin/uglifyjs
            
運用壓縮組件:
{% javascripts '@AppBundle/Resources/public/js/*' filter='uglifyjs2' %}
    <script src="{{ asset_url }}"></script>
{% endjavascripts %}

配置壓縮組件在debug時自動關閉, 在filter上加 "?"
{% javascripts '@AppBundle/Resources/public/js/*' filter='?uglifyjs2' %}
    <script src="{{ asset_url }}"></script>
{% endjavascripts %}

清理緩存, 壓縮重建dump文件


指定filter做用的文件

1. filter單獨某些文件:
直接在assetic標籤上標示filter

2. filter特定拓展名文件
# app/config/config.yml
assetic:
    filters:
        coffee:
            bin:        /usr/bin/coffee
            apply_to:   "\.coffee$"   //filter拓展名coffee格式的文件


圖片優化filter

1. Jpegoptim
# 安裝開發包 並配置 app/config/config.yml
assetic:
    filters:
        jpegoptim:
            bin: path/to/jpegoptim
            strip_all: true  //可選, 用於剔除EXIF信息
            max: 70  //圖片質量
            
使用
{% image '@AppBundle/Resources/public/images/example.jpg' filter='jpegoptim' output='/images/example.jpg' %}
    <img src="{{ asset_url }}" alt="Example"/>
{% endimage %}



簡短語法(twig函數)實現:
# 啓用配置 app/config/config.yml
assetic:
    filters:
        jpegoptim:
            bin: path/to/jpegoptim
    twig:
        functions:
            jpegoptim: ~ 或指定輸出目錄 { output: images/*.jpg }
            
使用   <img src="{{ jpegoptim('@AppBundle/Resources/public/images/example.jpg') }}" alt="Example"/>
相關文章
相關標籤/搜索