为了账号安全,请及时绑定邮箱和手机立即绑定

关于 symfony 的小常识!

标签:
PHP

学习三周symfony框架的小知识总结(杂乱无章的进行)。

1.首先我学习开始接触的是symfony2.8的,跟以前的版本中的目录结构不太一样。

2.一定要知道symfony的目录框架有哪些,不同的目录的作用。

3.假如我们要开发项目的话,我们要在哪里编写自己的代码以及要明白symfony是如何进行登录的,如何对用户进行验证 登录的过程我已经在另外一篇 地址:https://www.imooc.com/article/21323 欢迎点赞,评论,交流。

4.symfony的设计模型是什么,怎么使用模板,以及如何在模板中复制变量,循环遍历,在模板上加载css,js ,图片等 ,重要的是要知道symfony对模板是如何理解的,怎样继承并复写模板等。

5.如果要学习一个框架的话,我的习惯是先学习路由,那么sf是如何高效的进行的呢 还有验证路由。

6.sf是如何进行设置防火墙,如何设置用户权限,配置很多的路由规则的 比如annotation

7.sf是如何和数据库进行交互 的 比如表单,搜索,等。

8.sf中的命令 php app/console 命令可查看所有命令

9.composer 安装第三方的类库包,插件等等 自身的更新,安装bundle等操作

10.什么bundle,有什么作用呢,其翻译过来就是 束 捆 等含义。

以上是我学习了三个星期之后,学习成果,码出来,也是总结一下吧(比较乱哈,望看到的人对你有帮助)

现在我对以上写的问题进行回答,大神勿喷,欢迎对sf有更详细介绍,尽管帖出来。

问题 1:

目录结构的变化,其实不太大,主要还是你对这个框架的理解,根据以往的经验对其进行耐心,细心的学习,sf的目录大致的目录的作用

一级目录:

├── app     //这目录下包含了,配置文件(应用的配置文件会被import到这里面的配置文件中才生效)、缓存的类、缓存的模板
├── bin
├── composer.json
├── composer.lock
├── LICENSE
├── README.md
├── src                //我们编写的应用存放在这个目录下(包含Controller、Model、View、路由配置文件、应用的配置文件等)
├── vendor            //Symfony2的核心模块(HttpKernel组件、DependencyInjection组件等)和第三方插件(最常用的第三方插件SonataAdmin)存放在这目录下
└── web               //入口脚本文件存放在这目录下(app.php 生产环境访问的文件) (app_dev.php)开发环境访问的入口文件

以下为Symfony2二级目录和子目录的主要说明

web目录主要文件说明:

├── app_dev.php                          //调试模式下的入口文件(在调试模式下可以额外输出应用的运行信息,包括加载时间、执行的路由、执行sql语句等)
├── apple-touch-icon.png
├── app.php                              //生产环境下的入口文件(相当于TP框架index.php作用)
├── bundles
├── config.php
├── favicon.ico
├── robots.txt

app目录主要目录和文件说明:

├── AppCache.php
├── AppKernel.php       //入口文件里面会初始化一个AppKernel类,AppKernel类就是在这个文件里面,Appkernel类的主要功能是初始化整个web应用的Bundle。
                        //包括Symfony2框架的核心Bundle、第三方插件的Bundle、我们自己编写的应用的Bundle,Bundle在Symfony2里面就相当于一个具有完成
                        //某一功能的完整的包,而且我们要用的Bundle都必须在AppKernel类里面注册。

├── autoload.php       //该文件负责自动加载注册在里面的类,通常我们不需要手动修改它

├── bootstrap.php.cache //Symfony2核心的类的缓存文件,Symfony2框架必须用到的核心的类都会被编写整理到这个文件里面。这样做的目的是减少运行的时候打开
                       //文件的个数,提高运行的速度。因为不同的类都被存放在不同的文件里面,如果没有把这些必要的类缓存在一个文件里面,那么我们每次运行
                       //都要打开多个文件。如果把这些必要的类整理到一个文件里面,那么我们每次运行这些类就在同一个文件里面了。例如:Request类、Response类、
                       //Container类、Kernel类等都会被缓存到这个文件里面。所以,如果我们想在 Request类 里面 echo '在Request里面调试'; 这样的语句,我们就把
                       //这语句编写在bootstrap.php.cache文件下的Request类而不是symfony/vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Request.php
                     //里面的Request类。其实symfony/vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Request.php
                     //里面的Request类就被缓存到bootstrap.php.cache里了

├── cache            //缓存目录,按不同模式(生成模式、调试模式)缓存。主要缓存了模板文件、Container类、路由映射相关数据等
│   ├── dev
│   └── prod
├── check.php
├── config          //存放配置文件的目录,config_dev.yml和config_prod.yml才是被Symfony2框架加载的配置文件。但是为了方便管理,我们会把不同模块的配置
                    //编写到不同配置文件中,要使这些配置文件生效,那么我们还需要import它们进config_dev.yml和config_prod.yml。

│   ├── config_dev.yml      //调试模式的配置文件    
│   ├── config_prod.yml     //生成模式的配置文件
│   ├── config_test.yml
│   ├── config.yml         //通用的配置文件,只要import进相应的调试模式下的配置文件,就可以生效
│   ├── parameters.yml    //存放配置文件使用的变量,例如:数据名、数据库密码、数据库host等等
│   ├── parameters.yml.dist
│   ├── routing_dev.yml        //调试模式下的路由配置文件,我们在src里面编写的路由配置文件需要import到这个文件写才可以生效
│   ├── routing.yml            //通用路由配置文件
│   └── security.yml          //防火墙配置文件,这里的防火墙是web应用防火墙,不是服务器的防火墙,里面配置有角色权限、ACL等,这个文件需要config_*.php import进去才可以生效
├── console
├── logs                    //Symfony2运行的日志,同理,不同模式下有不同的日志
│   ├── dev.log
│   └── prod.log
├── phpunit.xml.dist
├── Resources
│   └── views
└── SymfonyRequirements.php

src下的一个demo的目录说明:

├── DemoBundle              //src目录下存放的就是我们应用层的代码,一个功能就可以组织成一个Bundle,例如简单一点的一个购物车功能、复杂一点的
                      //一个博客系统都可以组织成一个Bundle。
│   ├── AcmeDemoBundle.php     //记得app/AppKernel.php吗?每一个Bundle要被Symfony2框架加载并起作用,都需要把Bundle注册到AppKernel类,其实就是
                             //把这个文件里面的Bundle类注册到AppKernel类,我们可以手动添加到AppKernel类,也可以通过命令行生成一个Bundle的时候
                        //添加到AppKernel里面。
│   ├── Command
│   ├── Controller    //Controller目录,顾名思义,这个目录下存放的就是Controller类,如果不懂什么是Controller,麻烦请先学习MVC
│   ├── DependencyInjection  //该目录存放对AcmeDemoBundle的扩展
│   ├── EventListener       //该目录存放事件监听器的类,Symfony2框架是一个事件驱动的框架,不同的阶段会触发不同的时间,监听器只要监听相应的事件,
        //那么相应事件触发时,这些监听器就会被执行。如果刚接触不是很懂,可以不用太纠结,往后深入会接触到。
│   ├── Form     //该目录存放着表单类。
│   ├── Resources   //该目录存放着Bundle的配置文件、模板文件等
        ├── config
            ├── routing.yml  //该文件存放着Bundle的路由配置
            └── services.xml //该文件存放着Bundle的services配置
        ├── public
        └── views           //该文件夹存放着Bundle的所有模板文件
│   ├── Tests
│   └── Twig  

2.Twig定义了三种特殊的语法:

  • {{ ... }}
    “说些什么”:输出一个变量值或者一个表达式的结果到模板。
  • {% ... %}
    “做些什么”:控制模板逻辑的tag(标签),用于执行声明,如for循环语句等。
  • {# ... #}
    “进行注释”:它相当于PHP的 / comment / 语法。它用于注释单行和多行。注释的内容不作为页面输出。
    twig 模板上循环遍历 数组或者对象
    <ul>
    {% for user in users if user.active %}
    <li>{{ user.username }}</li>
    {% else %}
    <li>No users found</li>
    {% endfor %}
    </ul>

最主要的还是模板继承和布局:

此模板是我最开始写的模板。

{# app/Resources/views/base.html.twig #}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Test Application{% endblock %}</title>
    </head>
    <body>
        <div id="sidebar">
            {% block sidebar %}
                <ul>
                    <li><a href="/">Home</a></li>
                    <li><a href="/blog">Blog</a></li>
                </ul>
            {% endblock %}
        </div>

        <div id="content">
            {% block body %}{% endblock %}
        </div>
    </body>
</html>

父模板被存放在 app/Resources/views 目录,因此其路径是最简单的 base.html.twig。模板命名约定可参考下文的模板名称和位置。

模板继承的关键字是 {% extends %} 标签。 该标签告诉模板引擎首先评估父模板,它设置了布局并定义了若干blocks。然后子模板被输出,上例中父模板中定义的 title 和 body 两个blocks将会被子模板中的同名区块内容所取代。根据 blog_entries 的取值,输出的内容可能像下面这样:

{# app/Resources/views/blog/index.html.twig #}
{% extends 'base.html.twig' %} //此处我们继承上面的父级模板,即为上个页面的内容也会在这个页面显现出来
 //每个block 就相当于一块内容,一个页面是由多个block组成的。继承复写内容
{% block title %}My cool blog posts{% endblock %}

{% block body %}
    {% for entry in blog_entries %}
        <h2>{{ entry.title }}</h2>
        <p>{{ entry.body }}</p>
    {% endfor %}
{% endblock %}

拿在模板上怎样去加载css和js,图片呢

看代码吧 加载js文件

<script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="{{ asset('assets/libs/html5shiv.js') }}"></script>
<script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="{{ asset('assets/libs/respond.min.js') }}"></script>

也可以循环输出这些静态文件

{% for path in css() %}
  <link href="{{ asset('build/' ~ path) }}" rel="stylesheet" />
{% endfor %}

也可以使用一下的方式来定义文件的路径和图片路径。

app.uploadUrl = '{{ path("file_upload") }}';
app.imgCropUrl = '{{ path("file_img_crop") }}';
app.lessonCopyEnabled = '{{ setting("course.copy_enabled","0") }}';
app.cloudSdkCdn = '{{ setting("developer.cloud_sdk_cdn") }}';
app.lang = '{{ app.request.locale }}';

使用asset 函数去在模板上加载静态文件,当然了,最后你得去控制这些静态文件的版本 压缩他们。

路由,sf在访问项目中的路径是需要你自己在routing.yml 文件中 自己定义路由的路径 当然这个文件也可以加载一下路由文件 比如你有多个bundle 你想把路由分开谢,最后在一个文件里加载 ,看下面。

org_admin:
    resource: "@OrgBundle/Resources/config/routing_admin.yml"
    prefix:   /admin       //路由的前缀

custom_web:
    resource: "@CustomWebBundle/Resources/config/custom_routing.yml"
    prefix:   /

以上路由配置中 你可以根据不同的bundle去配置路由,那具体的怎样去配置路由呢。

我采用的是在routing.yml文件中配置,不使用annotation 方法。看下面的例子

homepage:
    pattern:  /
    defaults: { _controller: CustomsWebBundle:DemoDefault:index }

不过若你喜欢annotation路由配置模式也有这样的例子:

 /**
     * @Route(
     *     "/articles/{_locale}/{year}/{slug}.{_format}", 
     *     defaults={"_format": "html"},//参数后缀,加上html 在url里面这个地址就会显示XX/xx/xx/xx/xx.html
     *     requirements={
     *         "_locale": "en|fr",//defaults里面 第一个参数校验  下面也一样
     *         "_format": "html|rss",//只允许匹配html和rss后缀
     *         "year": "\d+"//只允许出现数字  \d  代表只要一位数自己即可, \d+ :代表一位或者多位数字即可
     *     }
     * )
     */
    public function listAction($page)
    {
        // ... //进行方法内的代码编写
    }

我们在custom_routing.yml 文件中像上面那样去写,homepage是键 是这个路由的代表,defaults

CustomsWebBundle 代表的意思是在src/custom 目录下的webbundle文件夹,DemoDefault代表的意思是依次的控制器文件夹的名字为demo,index 代表的意思是demo控制器下面的index方法。

pattern:意思是你访问defaults后 要跳转或者访问的路径 也可以添加参数(通配符{category})看下面的代码.

course_explore:
    pattern:  /course/explore/{category}
    defaults: { _controller: CustomWebBundle:DemoCourse:explore, category:'' }//后面可以追加参数,赋值等,也可以设置这个参数的默认值

聪明的你,----------现在知道上面代表的是什么意思吗?

随便说一下sf的security.yml 文件的威力。

这个文件可以干什么呢?看代码


       切记这些文件中不能使用table键  就是说你只能使用空格键进行调整格式

firewalls:
    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/    //我定义一个firewalls(防火墙)假如有人访问后缀为pattern的内容的文件  防火墙就会启动拦截请求。并返回security 的值。
        security: false

    main:
        pattern:    /.*
        form_login:
            login_path: login//表单提交的地址
            check_path: login_check//表单检测的地址
            use_referer: true
            failure_handler: xia.authentication.failure_handler//表单认证失败跳转的地址
            success_handler: xia.authentication.success_handler//表单认证成功跳转的地址
        remember_me://记住我的功能  
            secret: "%secret%"  //记录模式
            lifetime: 31536000  //记录密码的时间
            path: /         //路径
            domain: ~
        logout:          //退出
            path:   logout        //表单退出的方法 
            success_handler: xia.logout.success_handler //表单退出成功会去执行代码
        anonymous:  true     //登录用户的性质  {#anonymous 匿名的; 无名的; 假名的; 没有特色的;#}
access_control:         //权限的分配
    - { path: ^/task, role: ROLE_USER }//匹配访问以task开始的方法 要有ROLE_USER的权限才行,不然会返回登陆的页面,以下的验证同理。
    - { path: ^/my, role: ROLE_USER }
    - { path: ^/settings, role: ROLE_USER }
    - { path: ^/note, role: ROLE_USER }
    - { path: ^/message, role: ROLE_USER }
    - { path: ^/admin/course, role: ROLE_BACKEND }
    - { path: ^/admin/user, role: ROLE_BACKEND }
    - { path: ^/admin/app, role: ROLE_BACKEND }
    - { path: ^/admin/setting, role: ROLE_BACKEND }
    - { path: ^/admin/logs, role: ROLE_BACKEND }
    - { path: ^/admin/upgrade, role: ROLE_BACKEND }
    - { path: ^/admin/optimize, role: ROLE_BACKEND }
    - { path: ^/admin, role: ROLE_BACKEND }
    - { path: /.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/_internal, roles: IS_AUTHENTICATED_ANONYMOUSLY, ip: 127.0.0.1 }//也可以现在ip

现在来说说数据库 重要的部分来了,好像没有不重要的部分.

sf 会自动生成你想要的数据库的 表,甚至你可以用命令去实现 从建立数据库到创建表,创建字段 ,修改添加字段的属性等等,都可以用到命令。

关于数据库的的操作crud什么的:

//可以直接写sql语句。

$em=$this->getDoctrine()->getManager();$thosis->get('databases_connection')->fetchALL("sql语句);

//----sf  关于操作数据库的命令 app/console
--------------------------------------------------------------------------------------------------
app/console generate:doctrine:entities bundle的名称 //执行生成

bundleapp/console doctrine:schema:update --force  //执行生成已经定义完成的数据库

app/console doctrine:schema:update  --dump-sql //查看修改数据库的字段信息   

-------sf ---查询,修改,删除,数据

$user =$em->getRepository('user')->findOneBy(array("id"=>1));//查询用户表中 id = 的用户信息

$user ->setName('chengruoping');修改用户的名字 

$user ->reMove('chengruoping');删除用户的名字  

$em->presist($user);//托管变量

$em->flush();//刷新 持久化数据库

-----sf-调试sf在执行操作数据库字段之前 执行可查看将要执行的SQL语句

php app/console assetic:dump --env=prod --no-debug  

实现symfony自动生成静态文件 适用于 模板中的 fitter 和coffee 的属性。

表单自动创建带有lable,checkbox,choice,等样式表单

$task = new Task();
    $form = $this->createFormBuilder($task)
        ->add('task', 'label')//label
        ->add('public', 'checkbox', array(
            'label'     => 'Show this entry publicly?',
            'required'  => false,
        ));//复选框
        ->add('status', 'choice', array(
        'choice_list' => new ChoiceList(array(1, 0.5), array('Full', 'Half'))
        ));//也许是下拉框
        ->add('save', SubmitType::class, array('label' => 'Create Task'))
        ->getForm();
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        $task = $form->getData();
        return $this->redirectToRoute('task_success');
    }
    return $this->render('default/new.html.twig', array(
        'form' => $form->createView(),
    ));
}

接下来就是sf的第三方的安装包了,就是在目录中的 vender目录, 看看命令吧。

generate:bundle Generates a bundle //创建一个bundle

generate:controller Generates a controller //创建一个控制器

generate:doctrine:crud Generates a CRUD based on a Doctrine entity //创建一个curd的实例

generate:doctrine:entities Generates entity classes and method stubs from your mapping information //创建一个类和方法根据你的mapping

generate:doctrine:entity Generates a new Doctrine entity inside a bundle //创建一个实例

generate:doctrine:form Generates a form type class based on a Doctrine entity //创建一个form表单

以上就是我这边学习的几周的总结,有点混乱,有什么好的经验和坑欢迎来评论交流。

最后强调一下 在配置文件中切记不等用table键进行格式缩进,至于为什么,就靠大家去Google了。

点击查看更多内容
7人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消