如何在我的 PHP/SQL/HTML/CSS 代码上实现 MVC 风格?

2021-12-21 00:00:00 sql php html css model-view-controller

我一直在开发用于可视化某些数据的程序.我的程序从 MySQL 数据库获取特定输入并绘制一些图形(libchart 库),创建一些表格等.

I have been developing a program for the visualization of some data. My program takes specific input from a MySQL database and draws some graphs (libchart library), creates some tables etc.

我的问题是现在它是一个代码地狱.我有大约 7 个带有 HTML/CSS 和 PHP/SQL 代码的 php 文件(索引、图形页面、图库等)(其中一些只有 php 扩展名,但里面只有 HTML).我暂时阅读和理解该项目没有问题,但我想如果其他人尝试,他可能会头疼.另外,继续这样的编程是不切实际的,因为该项目将来可能不容易扩展.

My problem is that right now its a code hell in there. I have around 7 php files (index, graph-page, gallery, etc) with HTML/CSS and PHP/SQL code all together (some of them just have the php extension but have only HTML inside). I have no problem to read and understand the project for the time being, but I guess if someone else tried to, he might get a headache. Plus, continuing programming like this is not practical because the project might not be easily scalable in the future.

您对如何成功地将 HTML/CSS 与 PHP/SQL 分开有什么建议吗?我不想使用框架,因为我没有做任何需要用户输入、会话处理等的事情.我只是运行一些查询并将结果可视化.我在这里主要谈论架构,如果适用,也许可以帮助我的脚本(我已经阅读了 Smarty,但我不确定这是否是我需要的).

Do you have any suggestion on how to successfully seperate HTML/CSS from PHP/SQL? I don't want to use a framework since I'm not doing anything that requires user-input, session handling, etc. I just run some queries and visualize the results. I'm mostly talking about architecture here, and if applicable perhaps a script to help me (I've read about Smarty but I'm not sure if that's what I need).

推荐答案

对于如何成功地将 HTML/CSS 与 PHP/SQL 分离,您有什么建议吗?

Do you have any suggestion on how to successfully seperate HTML/CSS from PHP/SQL?

恭喜您了解如何改进代码.这是前提条件,你需要想改进它,而且这个话题很长.所以你的意愿很重要.

Congrats for looking how you can improve code. That's the precondition, you need to want to improve it and the topic is lengthy. So your will is crucial.

我很轻松地开始,然后尝试提供一些提示.如果您缺少经验,请寻找一个起点,当然是下面列表中的最后一个.但首先要注意的是:

I start lightly and then try to give some tips. As you're missing experience, look for one point to start with, most certainly the last one of the list below. But first things first:

要将某些东西彼此分开,您需要有一些代码来分开:

To separate something from each other, you need to have some code that separates:

[HTML/CSS/PHP/SQL]

[HTML/CSS] <--> [SEPARATOR] <--> [PHP/SQL]

这里的分隔符实际上也是 PHP 代码,但我想你明白了.

The Separator here actually is PHP code as well, but I think you get the idea.

正如您所看到的,只有 Separator 与 HTML/CSS 和 PHP/SQL 对话.

As you can see only the Separator talks with HTML/CSS and PHP/SQL.

所以 HTML/CSS 和 PHP/SQL 都需要有一个带有 Separator(之间的线)的接口来完成这项工作.

So both HTML/CSS and PHP/SQL need to have an interface with Separator (the line between) to make this work.

通常在程序中,您会传递经过处理的数据.数据非常动态,可能具有复合复杂性,尤其是当您将数据传递给应正确格式化的输出例程时.

Normally in a program you pass around data that get's processed. The data is pretty dynamic and can have a compound complexity, especially if you pass data to an output routine that should format it properly.

有多种方法可以编写这样的分隔符(或多个分隔符).您可以分层您的软件或提供在其区域或域中执行操作的组件.例如.你有一个数据库层或数据库组件来处理与数据库的交互.

There are multiple ways of how such a Separator (or multiple of them) can be written. You can layer your software or provide components that do things in their area or domain. E.g. you have a database layer or database component that takes care about the interaction with the database.

或者您有一个模板引擎,负责将您的字符串和数组放入一些可读的 HTML 中.

Or you have a templating engine that takes care to put your strings and arrays into some readable HTML.

简而言之,这就是软件设计的通心粉理论:

In short this is the pasta theory of software design:

  • 意大利面代码 - 合而为一,代码高度交织,最好与 Bolognese 或 Aglio、Olio e Peperoncino 搭配.
  • 千层面代码 - 分层,一层有另外两层与之交互(除非底部或顶部),总是用白酱汁.
  • Tortelini 代码 - 小部件,只做自己的工作,里面有肉或辣蔬菜.
  • Spaghetti code - all in one, code is heavily interwoven, preferable with Bolognese or Aglio, Olio e Peperoncino.
  • Lasagne code - Layered, one layer has two other layers it interacts with (unless bottom or top), always with Béchamel sauce.
  • Tortelini code - Small components that just do their job, they have Meat or Spicy Vegetables inside.

就像我们在生活中吃不同的意大利面一样,在编程时我们也需要处理所有这些不同类型的代码,并且随着时间的推移我们会形成自己喜欢的口味.小时候我们吃饱,但随着时间的推移,我们开始自己做饭并改变食谱.

Like we eat different pasta in our lives, when programming we need to deal with all these different type of code as well, and we develop our own preferred taste over time. As a kid we're feed but over time we start to cook something our own and vary the recipes.

所以我认为这是一个很好的观点,你只是不想在接下来的几周内吃 MVC Framework X 和很多很棒的,只是因为有人告诉你这是现在吃的方式.在吃之前,有品尝,对吧?更不用说快餐了,你知道像这些带酱汁的面条——只加水.呃.

So I think it's a good point you just don't want to now eat MVC Framework X with much awesome for the next weeks only because somebody told you it's the way to eat now. And before eating, there is tasting, right? Not to mention fast-food, you know like these noodles with sauce in package - only add water. Urgh.

我不知道您的输出需要哪些数据以及输入是什么.以下是输出 HTML/CSS 并与 MySQL 数据库交互的应用程序的一些粗略重构技巧.这不能是一个完整的列表,描述只能粗略地勾勒出一些想法:

I don't know which data your output needs and what the input is. Following are some rough refactoring tips for applications that output HTML/CSS and interact with a MySQL database. This can not be a complete list and the descriptions can only roughly outline some thoughts:

  • 将 CSS 移出 HTML.在链接的 CSS 定义中有效地使用选择器并替换任何 style 属性(如果您还有一些).这使您的 CSS 代码可重用且更加模块化.它将帮助您找到 HTML 中的缺陷并将结构 (HTML) 与演示文稿 (CSS) 分开.有效的 HTML 始于对 CSS 的有效使用,这两者结合起来非常强大,通常这已经可以减轻您的程序输出例程.
  • 将业务逻辑从 HTML 中移出.HTML 和您的代码都可能是野兽,因此最好将它们分开.它们有相互争斗的倾向,而且由于两者都非常强大,因此在您开发应用程序时争斗将继续,这会分散您对需要做的工作的注意力.
    考虑一下您是否需要在应用程序中已经有复杂的输出,或者您是否可以只传递带有子元素的数组(一个键是一个 var,一个 var 可以包含一个字符串或数字或另一个 var 数组).通常,即使是将复杂的数据传递到视图或模板,都需要这样做.然后,您的 HTML 只需要在子数组上回显一些数组成员和/或 foreach.这是创建模板的一种非常简单的技术.您可以使用 PHP,因此您实际上非常灵活(只需绘制属于您的视图层和应用程序的一部分的代码的边框,例如为视图提供值).
  • 将 SQL 从代码中移出.将数据库交互代码移开.自己创建一个或多个对象,这些对象具有在实际处理代码中以您需要(使用)数据的方式返回数据的方法,例如 $component->getThatData() 然后以一种方式返回数据规范化形式.制作这些组件,然后使用专用的数据库组件与数据库进行对话.在您的应用程序代码(业务逻辑)中,仅使用数据库组件,最好使用您创建的对象来获取数据,因此您的主代码中不再有任何 SQL 行.
  • 分而治之您的应用程序代码:将您的代码分成事务脚本.它们通常很容易从现有的意大利面条式代码创建,并且很可能成为您在中间寻找的所述分隔符.然后,他们将负责处理数据并将其传递(到输出/视图中).
  • 使用清晰的语言:如果您有未规范化的复杂格式化字符串数据,请自己编写Parser 类来为您完成工作并且可以轻松重新使用(如果您的应用程序是这种情况).由于您应该期待尽量减少在代码中使用纯 SQL,您还应该期待将复杂的正则表达式移走.封装变化是一个关键点.这同样适用于仅处理某些数据的长例程(例如,以另一种格式对其进行排序、排序和排列),将它们移动到各自的组件中,并考虑如何使它们可访问和可重复使用.
  • 使您的代码正常运行:了解您如何在程序中调用功能的逻辑.您可以尝试将功能与其调用方式分开.例如.一些调用任何事务脚本的例程.如果您直接通过浏览器请求 PHP 文件,这可能不是必需的,因为这些是您的交易脚本,并且网络服务器会小心地将通过 URL 发送到您的应用程序的命令解析为交易脚本.但是,您应该将处理传入命令及其参数所需的任何逻辑包装到可重用的组件中(例如,Request 类包含用于获取 URL 和或来自 HTTP 请求的变量).
  • 通过在通过浏览器调用的所有文件的最顶部包含相同的文件来创建一个公共入口点.然后,您可以将通用代码(例如设置应用程序会话状态 对象和初始化数据库组件)放入其中,另请参见 应用控制器
  • 通过查找字面上重复的代码来消除重复.将它包装成一个函数或类.为您自己的应用程序创建一个库文件夹,将包含的内容放入其中.如果您遵循类名和命名空间的通用模式,您可以轻松使用自动加载器来保持轻松包含.使您的库与第三方代码分开.将所有第三方代码放入自己的库文件夹中,每个第三方组件都有一个子目录.
  • 使用轻量级的现有组件.轻量级很重要,因为您已经拥有自己的代码,您不想一次性将其全部转换并压在框架上.现有很重要,因为您不想重新发明轮子.您将有足够的工作来重构您的代码.在您对您的应用程序感觉更好并且您仍然拥有权力和意愿之后,您可以随时编写新的内容.但是,如果您是独自一人或在一个小团队中,Existing 非常强大.简单的库例如:
    • 模板引擎:Mustache
    • 数据库层:NotORM
    • Move CSS out of HTML. Use selectors effectively in the linked CSS definition and replace any style attributes if you still have some. This makes your CSS code re-useable and more modular. It will help you to find flaws inside your HTML and to separate the Structure (HTML) from the Presentation (CSS). Effective HTML start with effective usage of CSS, those two are very powerful together and often this already will lighten your programs output routines.
    • Move business logic out of HTML. Both HTML and your code can be a beast, so better keep them apart. They have the tendency to fight with each other, and as both are very powerful, the fight will continue while you develop your application, that distracts you from the work you need to do.
      Consider if you need to already have complex output inside your application or if you can just pass on arrays with subelements (a key is a var, a var can contain a string or number or another var-array). Normally that is all needed to pass even complex data into a view or template. You HTML then only needs to echo some array members and or foreach over subarrays. This is a very simple technique to create a template. You can use PHP for it, so you're actually really flexible (just draw the border which code belongs into your view layer and which is part of the application, e.g. providing values for the view).
    • Move SQL out of your code. Move the database interaction code away. Create yourself one or multiple objects that have methods which return the data in a way you need (consume) it in your actual processing code, like $component->getThatData() which then returns data in a normalized form. Make those components then use a dedicated database component to talk over with the database. In your application code (business logic) only use the database component and preferably the objects you create to get the data, so you don't have any line of SQL any longer inside your main code.
    • Divide and Conquer your application code: Divide your code into Transaction Scripts. They are often easy to create from existing spaghetti code and will be probably become the said Separator you're looking for in middle terms. They will then have the role to process data and passing it on (into the output/view).
    • Use clear language: If you have complex formatted string data that is not normalized, write yourself Parser classes that do the work for you and which can be easily re-used (if that's the case in your application). As you should look forward to minimize the use of plain SQL in your code, you should also look forward to move complex regular expressions away as well. Encapsulate what varies is a key point. Same applies to long routines to just handle some data (e.g. sort, order and arange it in another format), move them into components of each own and think about how you can make them accessible and re-useable.
    • Make your code functioning: Find out about the logic how you invoke functionality in your program. You can try to separate functionality away from how it's invoked. E.g. some routine that invokes any of the Transaction Scripts. This might not be necessary if you request PHP files directly via the browser, as those are then your transaction scripts and the webserver takes care to resolve the command send via URL into your application to the transaction script. But you should then wrap any logic needed to process the incoming command and it's parameters into re-useable components (e.g. a Request class that contains standard code to get the URL and or variables from a HTTP request).
    • Create a common entry-point by including the same file at the very top of all files that are called via the browser. You can then put common code (like setting up the application session state object and initializing the database component) into it, see as well Application Controller
    • Remove duplication by looking for literally duplicated code. Wrap it into a function or class. Create a library folder for your own application into which you put your includes. If you follow a common pattern with Classnames and Namespacing, you can easily use an autoloader to keep inclusion easy. Make your library apart from third-party code. Place all third-party code into a library folder of it's own with one subdirectory for each third-party component.
    • Use lightweight, existing components. Lightweight is important because you have your own code already, you don't want to turn and press it all at once onto a framework. Existing is important because you don't want to re-invent the wheel. You will have enough work for your own refactoring your code. After you feel better about your application and you still have power and will, you can always write everything new. But if you're alone or in a small team, Existing is pretty powerful. Simple libraries are for example:
      • Templating engine: Mustache
      • Database layer: NotORM

相关文章