taaaang
V2EX  ›  PHP

PHP 的 sql 到底该写在哪儿?

  •  
  •   taaaang · Apr 13, 2020 · 9562 views
    This topic created in 2400 days ago, the information mentioned may be changed or developed.

    最近刚接触 PHP,过了一遍 PHP 官方文档和 thinphp 的官方文档就开干。然后用到原生 sql,不知道正常情况应该写在哪儿更合适,controller ? 还是单独整一层? 或者一起放在 model 里面? 求大佬们指点下,怎么搞看起来专业一点。。。

    66 replies  •  2020-05-25 11:38:41 +08:00
    zooo
    zooo
    Apr 13, 2020
    1
    controller
    service
    dao

    dao 层里面写

    data access object
    taaaang
    taaaang
    OP
    Apr 13, 2020
    2
    @zooo
    我一直是搞 java 方面的,最近因为做兼职项目所以搞 PHP 。 根据 thinkphp 文档来看,就提供了 controller 和 model,然后 model 主要是封装了模型的基本操作。看了一个叫 apiadmin(基于 thinkphp)的开源项目,一些数据库操作它直接就在 controller 里面写了, 很迷
    chotow
    chotow
    Apr 13, 2020 via iPhone
    3
    Controller 注入 Service,Service 注入 Repository 。
    我个人不喜欢 DAO,所以用 Repository 。
    如果项目不大,直接在 Service 操作 DB 。
    zooo
    zooo
    Apr 13, 2020
    4
    Repository 和 dao 差不多吧? 换个名字
    m939594960
    m939594960
    Apr 13, 2020
    5
    @zooo #1 搞 PHP 就搞 PHP 用啥 dao 命名? 这个词除了在 java 里有意义之外还有什么实际意义么?
    2kCS5c0b0ITXE5k2
    2kCS5c0b0ITXE5k2
    Apr 13, 2020
    6
    我个人做法是用 trait 封装一些常用的方法。 然后在 model 层写。php 没那么严谨 写在那层都可以
    m939594960
    m939594960
    Apr 13, 2020
    7
    @zooo #1 搞 PHP 就搞 PHP 用啥 dao 命名? 这个词除了在 java 里有意义之外还有什么实际意义么?
    AngryPanda
    AngryPanda
    Apr 13, 2020
    8
    @m939594960 微软也用呢。
    2kCS5c0b0ITXE5k2
    2kCS5c0b0ITXE5k2
    Apr 13, 2020
    9
    tp 的 model 层类似 Java 里面的 service 层+dao 层的合体。
    sagaxu
    sagaxu
    Apr 13, 2020 via Android
    10
    tp 用户,写哪都行,就是混在 html 里问题也不大
    yxwzaxns
    yxwzaxns
    Apr 13, 2020 via iPhone
    11
    都是老千层饼啊
    zooo
    zooo
    Apr 13, 2020
    12
    @m939594960 赞同 你
    Takamine
    Takamine
    Apr 14, 2020 via Android
    13
    写在 model 吧,然后自己在 model 和 controller 之间加个 service 层。
    heyjei
    heyjei
    Apr 14, 2020
    14
    写在 controller 里,不然就对不起 Quick And Dirty 这个称号,复杂且会存在共用的逻辑才抽取出来放 Service 里。Model 负责定义数据模型,不要把逻辑放里面了。
    guolaopi
    guolaopi
    Apr 14, 2020
    15
    楼上说的写到 model 里是要把 model 做成 DDD 里的充血模型(滑稽
    hbolive
    hbolive
    Apr 14, 2020
    16
    既然兼职的,controller 里干就是了,讲究那么多干啥。。
    2kCS5c0b0ITXE5k2
    2kCS5c0b0ITXE5k2
    Apr 14, 2020 via iPhone
    17
    @guolaopi 学习了 之前写的小项目都是写在 model 里面的 确实有点不合理 还是抽离出一个 service 层比较好管理 和解耦
    kaiki
    kaiki
    Apr 14, 2020
    18
    看给多少钱,钱少我就哪里需要写哪里,钱多就规范点。
    专不专业得看谁来看的,如果对方啥都不懂,那你写啥都专业。
    avenger
    avenger
    Apr 14, 2020 via iPhone
    19
    model 里面用 orm,不写 sql 🐶
    815979670
    815979670
    Apr 14, 2020 via Android
    20
    有 orm,调用对象就行了
    tabris17
    tabris17
    Apr 14, 2020 via iPhone
    21
    没必要抽象出 dal,事实上项目是不可能切换数据库的
    taaaang
    taaaang
    OP
    Apr 14, 2020
    22
    @chotow @m939594960 @sagaxu @Takamine @heyjei @hbolive
    首先感谢大佬们的围观。
    如果用 service 来封装共用逻辑,你们怎么命名文件的呢? 类似于 java 的 xxxService ? 我想既然干 php 就得像 php 。 大部分时候 model 够用,主要是有一些原生 sql 写在 controller 里面,代码文件显得很长了,也确实有一些逻辑需要抽取出来。

    我居然因为一个代码组织的问题来专门提个问题,也真是心累了。。。
    AlanLeung2018
    AlanLeung2018
    Apr 14, 2020
    23
    tp 框架,建议写在 model 层
    jfhy0901
    jfhy0901
    Apr 14, 2020 via Android
    24
    一般都是写在 C 里面,M 里面做一些关联模型等。兼职不要讲究那么多,我接手的一个项目,一个 C 里面写了一万行你敢信?
    zjsxwc
    zjsxwc
    Apr 14, 2020
    25
    有 ORM 就按照 ORM 推荐的用法来写,sql 写在 Repository 和 Entity 里都可以,一般都是类 sql 的方言比如 linq 、dql 等,反正都是 Entity 实体对象处理,entity manager 会自动搞定。

    如果是类似 mybatis 的框架 sql 就写到 mapper xml 文件里,花点时间自己手动构造每个 DAO 。

    其他比如 PDO 这种全局变量的,哪里都能写,你安自己项目需求写呗,只要合理就行。
    guolaopi
    guolaopi
    Apr 14, 2020
    26
    @emeab
    我瞎说的啊,我不做 PHP,只是给我的感觉像充血模型一样
    edk24
    edk24
    Apr 14, 2020
    27
    用 sql 少, 我觉得可以写在 controller 里, 但这个 sql 常用到可以写在 model 方便复用
    handsomehaitao
    handsomehaitao
    Apr 14, 2020
    28
    service 与 response 里
    encro
    encro
    Apr 14, 2020
    29
    一般不用写 sql 了吧,复杂查询用 orm 自动关联出来。

    如果需要对一些操作进行封装,比如对多个批量操作采用事务,可以写在 model,便于复用。

    其实不用太在乎写在哪里,而应该在乎是否好用好用,便于用即可,实际写写看。

    比如用户充值,需要修改余额和生成充值记录,那么直接用$user->recharge($money)我觉得是比较方便和复用的,那么对我来说就是适合的,
    因为如果写在控制器里面,那么不能复用,
    如果单独抽取 service 层,你用的时候就得 UserService::Recharge($user_id,$money),UserService 里面你得再次实例化 User,当然你也可以直接传$user 进去,但是我懒。
    代码怎么简单明了够用就怎么写吧,大部分时候代码行数越少就越容易维护。
    m939594960
    m939594960
    Apr 14, 2020
    30
    一般的项目,一般我就写到 controller 或者 service 里了
    absolutelynull
    absolutelynull
    Apr 14, 2020
    31
    数据处理的话 可以写在 model 层,单纯的 crud 的话 实例化模型在 controller 写入
    Varobjs
    Varobjs
    Apr 14, 2020 via Android
    32
    写在哪里都可以,
    如果简单的, 写 c 里也行吧,如果多处用,就写 service 里,如果很多 service 用,那就再单独一层
    brader
    brader
    Apr 14, 2020
    33
    用 php 框架就尽量不要写原生 sql 了,php 框架的数据库操作非常完善和好用,如果某些特殊的需要写原生 sql,直接写就是了,一点都不要担心,我保证,这样的特例,是极少数的,并不会对后期造成太大的困扰
    skys215
    skys215
    Apr 14, 2020
    34
    在只有 controller 和 model 的情况下
    有重 controller 轻 model,重 model 轻 controller 两种方式。
    重 controller 的话,前端在做某些操作的时候要调用同一个 api
    重 model 的话,就没有这个问题,但也有一些问题。例如,相似的操作会在方法里多次定义。
    所以才会引入中间层 repository/service (怎么叫都无所谓了)。model 就只写相关定义,例如表名、主键名、枚举值之类的。
    ben1024
    ben1024
    Apr 14, 2020
    35
    新建一个 Repository 层,写在 Repository 里
    0x663
    0x663
    Apr 14, 2020
    36
    写 html 里边
    Takamine
    Takamine
    Apr 14, 2020 via Android
    37
    @taaaang Service 可以直接和 Controller 同名服务于 Controller,把 Controller 的复杂逻辑抽出来到 Service 。
    PHP 框架的 orm 和楼上说的一样都比较完善了,model 做映射之后直接给 service 层提供服务,你 sql 也这样写在 model 里面给 Service 提供服务,感觉合理一点。
    james122333
    james122333
    Apr 14, 2020 via Android
    38
    我之前替公司弄的小型框架写在 service controller 负责回应 只是写个类
    每次都
    $mysql->connect();
    $data = $mysql->query("
    select...
    ", array(
    参数替换
    ));
    这样就可以了 用 orm 只是增加複杂度
    Dao model 通通省了
    php 字串里可加变量 "$abc" 动态性已经足够了
    完成一样的事情 java 就啰唆非常多
    又简单又动态的感觉是爽度
    MonoLogueChi
    MonoLogueChi
    Apr 14, 2020
    39
    @m939594960 dao 不是 java 专属的呢
    james122333
    james122333
    Apr 14, 2020 via Android
    40
    connect()里面还可以加入 ip 使用者 选项类
    顶多再弄个 enum 解决回家睡觉
    dobelee
    dobelee
    Apr 14, 2020 via iPhone
    41
    只是临时简单用到的话不用特意抽一层,简单写到 html 里...哦不 controller 里就 ok 了。🐶
    airflybusoren
    airflybusoren
    Apr 14, 2020
    42
    一直写 model 那,跟 java 不一样
    m939594960
    m939594960
    Apr 14, 2020
    43
    @MonoLogueChi #39 哪 dao 什么意思?是什么的简写?有什么含义?我以后管 model 叫 Eloquent 管 view 叫 blade 管 route 叫 fasterouter 可以么?
    shenjia
    shenjia
    Apr 14, 2020
    44
    只用过 Yii 框架的 ActiveRecord,一开始感觉链式调用还挺爽的……后来发现还是用 sprintf 手拼 sql 最实在,性能可控,线上有慢查询了好定位,一搜一个准。
    iyaozhen
    iyaozhen
    Apr 14, 2020
    45
    其实你会 java 的话按 java 一模一样来就行
    james122333
    james122333
    Apr 14, 2020 via Android
    46
    @dobelee
    这不如直接写一个脚本就好...
    "超文本预处理器"...
    yogogo
    yogogo
    Apr 14, 2020
    47
    我是再加了一层 logic 层,就是类似 service
    hantsy
    hantsy
    Apr 14, 2020
    48
    你们写 php 不用 Doctrine 吗?
    james122333
    james122333
    Apr 14, 2020 via Android
    49
    @shenjia
    手拼外加封装"一个"类 会更爽
    那些写设定的不知道在想什么
    设定再动态也不会比语言动态
    只要不要写成$xxx->select()->from()类似的就可以了
    hantsy
    hantsy
    Apr 14, 2020
    50
    @shenjia ActiveRecord 模式最成功是 CakePHP,还进行很多封装,简单易用。
    lzj307077687
    lzj307077687
    Apr 14, 2020
    51
    一般开一层 Repository 或者 Service
    要快的话直接 Controller
    predator
    predator
    Apr 14, 2020❤️6
    52
    不是说 DAO 专不专于什么的问题,也不是说 PHP 要怎么写显得“专业”一些的问题
    ThinkPHP 或者类似的框架,本来就有文档去规范要把可重用的数据库操作写在 model 里面

    有些人接手公司的项目,连框架规范都不愿意看,model 里面套 service,service 里面再套 dao,自己觉得在 IDE 里面爽得不行,完全大傻逼

    dao 你妈逼 dao
    HUALIAN
    HUALIAN
    Apr 14, 2020
    53
    dao 哈哈 笑死我了🐎的
    Heartbleed
    Heartbleed
    Apr 14, 2020
    54
    常用的 SQL 写在 model 好一点,逻辑清晰
    G4vin
    G4vin
    Apr 14, 2020
    55
    要不是学过两个月的 java 我真没听过 dao 是什么鬼。。。。
    james122333
    james122333
    Apr 14, 2020 via Android
    56
    @Heartbleed
    是阿 是"常用" model 不一定必须
    yoshiyuki
    yoshiyuki
    Apr 14, 2020
    57
    model 层
    lepig
    lepig
    Apr 14, 2020
    58
    能不能别整天在那 dao 比 dao

    ![c9sA.png]( https://u.vmpic.cn/2020/04/14/c9sA.png)
    Heartbleed
    Heartbleed
    Apr 14, 2020
    59
    “dao 你妈逼” 的那位笑死我了 hhhh
    dvaknheo
    dvaknheo
    Apr 14, 2020❤️1
    60
    Service/Logic 跟业务走。
    Model/Repository 跟表走 如果是附属表也可以不那么严格。

    比如用户充值,需要修改余额和生成充值记录,那么直接用$user->recharge($money)我觉得是比较方便和复用的,那么对我来说就是适合的,

    按业务来分的话
    UserService::Recharge($user_id,$money)
    这个走 RechargeModel 还可能要用到 LogModel 还看看用户是否有钱 UserInfoModel
    UserService::GetProfile($user_id)
    用 UserInfoModel
    tokyo2020
    tokyo2020
    Apr 14, 2020
    61
    Infrastructure
    baobao1270
    baobao1270
    Apr 15, 2020 via Android
    62
    model 里 或者 orm
    couashi
    couashi
    Apr 15, 2020
    63
    @zooo 直接让他学 spring 算了
    hiColin
    hiColin
    Apr 15, 2020
    64
    sql 写在 model 层,一般使用 orm 操作数据库,不推荐直接使用原生 sql 语句,除非 orm 无法完成的查询。
    kylesean
    kylesean
    May 7, 2020
    65
    拆分 Service 里用 ORM 写,一般的项目够了。扯什么 Dao 层 Repository 层,PHP 项目有个要这样拆分?不要跟我扯以后换什么数据库,什么单元测试方便。没有以这一层,代码可读性,扩展维护性都很方便。PHP 就要有 PHP 的样子,听到别人扯 Dao 层就来火,框架的 ORM 或者 ActiveRecord 设计模式本身就是轻量级的 Dao 层。PHP 分个 4 、5 层就是脱裤子放屁。
    QlanQ
    QlanQ
    May 25, 2020
    66
    php 要什么 dao ? model 不够用?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1562 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 123ms · UTC 13:51 · PVG 21:51 · LAX 05:51 · JFK 08:51
    ♥ Do have faith in what you're doing.