手把手编写PHP MVC框架实例教程
目录
1 什么是MVC
MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式。
MVC把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
PHP中MVC模式也称Web MVC,从上世纪70年代进化而来。
MVC的目的是实现一种动态的程序设计,便于后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。
除此之外,此模式通过对复杂度的简化,使程序结构更加直观。
MVC各部分的职能:
- 模型Model – 管理大部分的业务逻辑和所有的数据库逻辑。模型提供了连接和操作数据库的抽象层。
- 控制器Controller - 负责响应用户请求、准备数据,以及决定如何展示数据。
- 视图View – 负责渲染数据,通过HTML方式呈现给用户。
一个典型的Web MVC流程:
- Controller截获用户发出的请求;
- Controller调用Model完成状态的读写操作;
- Controller把数据传递给View;
- View渲染最终结果并呈献给用户。
2 为什么要自己开发MVC框架
网络上有大量优秀的MVC框架可供使用,本教程并不是为了开发一个全面的、终极的MVC框架解决方案。
我们将它看作是一个很好的从内部学习PHP的机会。
在此过程中,你将学习面向对象编程和MVC设计模式,并学习到开发中的一些注意事项。
更重要的是,通过自制MVC框架,每个人都可以完全控制自己的框架,将你的想法融入到你的框架中。
这不是很美妙的事情吗~~~
3 准备工作
3.1 环境准备
这里我们需要最基本的PHP环境:
- Nginx或Apache
- PHP5.4+
- MySQL
推荐使用phpStudy或docker一键安装这样的LNMP环境。
3.2 代码规范
在目录设置好以后,我们接下来规定代码的规范:
- MySQL的表名需小写或小写加下划线,如:
item
,car_orders
。 - 模块名(Models)需用大驼峰命名法,即首字母大写,并在名称后添加
Model
,如:ItemModel
,CarModel
。 - 控制器(Controllers)需用大驼峰命名法,即首字母大写,并在名称后添加
Controller
,如:ItemController
,CarController
。 - 方法名(Action)需用小驼峰命名法,即首字母小写,如:
index
,indexPost
。 - 视图(Views)部署结构为控制器名/行为名,如:
item/view.php
,car/buy.php
。
上述规则是为了程序能更好地相互调用。
接下来就开始真正的PHP MVC编程了。
3.3 目录准备
在开始开发前,我们给这个框架先起个名字吧,就叫:Fastphp框架。
然后根据需要来把项目的目录创建。
假设我们建立的项目为 project,目录结构就这样:
project WEB部署根目录 ├─app 应用目录 │ ├─controllers 控制器目录 │ ├─models 模块目录 │ ├─views 视图目录 ├─config 配置文件目录 ├─fastphp 框架核心目录 │ ├─base MVC基类目录 │ ├─db 数据库操作类目录 │ ├─Fastphp.php 内核文件 ├─static 静态文件目录 ├─index.php 入口文件
然后按照下一步,把Nginx或者Apache的站点根目录配置到project
目录,。
3.4 重定向
重定向的目的有两个:设置根目录为project
所在位置,以及将所有请求都发送给 index.php 文件。
如果是Apache服务器,在 project 目录下新建一个 .htaccess 文件,内容为:
<IfModule mod_rewrite.c> # 打开Rerite功能 RewriteEngine On # 如果请求的是真实存在的文件或目录,直接访问 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # 如果访问的文件或目录不是真事存在,分发请求至 index.php RewriteRule . index.php </IfModule>
server
块中加入如下的重定向:location / {
# 重新向所有非真是存在的请求到index.php
try_files $uri $uri/ /index.php$args;
}
(1)静态文件能直接访问。
如果文件或者目录真实存在,则直接访问存在的文件/目录。
比如,静态文件static/css/main.css
真实存在,就可以直接访问它。
(2)程序有单一的入口。
这种情况是请求地址不是真实存在的文件或目录,这样请求就会传到 index.php 上。
例如,访问地址:localhost/item/detail/1
,在文件系统中并不存在这样的文件或目录。
那么,Apache或Nginx服务器会把请求发给index.php
,并且把域名之后的字符串赋值给REQUEST_URI
变量。
这样在PHP中用$_SERVER['REQUEST_URI']
就能拿到/item/detail/1
;
(3)可以用来生成美化的URL,利于SEO。
4 PHP MVC核心文件
4.1 入口文件
接下来,在 project 目录下新建 index.php 入口文件,文件内容为:
<?php // 应用目录为当前目录 define('APP_PATH', __DIR__ . '/'); // 开启调试模式 define('APP_DEBUG', true); // 加载框架文件 require(APP_PATH . 'fastphp/Fastphp.php'); // 加载配置文件 $config = require(APP_PATH . 'config/config.php'); // 实例化框架类 (new fastphp\Fastphp($config))->run();
?>
。?>
,4.2 配置文件
在入口文件中,我们加载了config.php文件的内容,那它有何作用呢?
从名称不难看出,它的作用是保存一些常用配置。
config.php 文件内容如下,作用是定义数据库连接参数参数,以及配置默认控制器名和操作名:
<?php // 数据库配置 $config['db']['host'] = 'localhost'; $config['db']['username'] = 'root'; $config['db']['password'] = '123456'; $config['db']['dbname'] = 'project'; // 默认控制器和操作名 $config['defaultController'] = 'Item'; $config['defaultAction'] = 'index'; return $config;
入口中的$config
变量接收到配置参数后,再传给框架的核心类,也就是Fastphp
类。
4.3 框架核心类
$config
参数配置,并保存到对象属性中。run()
方法则调用用类自身方法,完成下面几个操作:- 类自动加载
- 环境检查
- 过滤敏感字符
- 移除全局变量的老用法
- 路由处理
fastphp
目录下新建核心类文件,名称Fastphp.php,代码:<?php namespace fastphp; // 框架根目录 defined('CORE_PATH') or define('CORE_PATH', __DIR__); /** * fastphp框架核心 */ class Fastphp { // 配置内容 protected $config = []; public function __construct($config) { $this->config = $config; } // 运行程序 public function run() { spl_autoload_register(array($this, 'loadClass')); $this->setReporting(); $this->removeMagicQuotes(); $this->unregisterGlobals(); $this->setDbConfig(); $this->route(); } // 路由处理 public function route() { $controllerName = $this->config['defaultController']; $actionName = $this->config['defaultAction']; $param = array(); $url = $_SERVER['REQUEST_URI']; // 清除?之后的内容 $position = strpos($url, '?'); $url = $position === false ? $url : substr($url, 0, $position); // 删除前后的“/” $url = trim($url, '/'); if ($url) { // 使用“/”分割字符串,并保存在数组中 $urlArray = explode('/', $url); // 删除空的数组元素 $urlArray = array_filter($urlArray); // 获取控制器名 $controllerName = ucfirst($urlArray[0]); // 获取动作名 array_shift($urlArray); $actionName = $urlArray ? $urlArray[0] : $actionName; // 获取URL参数 array_shift($urlArray); $param = $urlArray ? $urlArray : array(); } // 判断控制器和操作是否存在 $controller = 'app\\controllers\\'. $controllerName . 'Controller'; if (!class_exists($controller)) { exit($controller . '控制器不存在'); } if (!method_exists($controller, $actionName)) { exit($actionName . '方法不存在'); } // 如果控制器和操作名存在,则实例化控制器,因为控制器对象里面 // 还会用到控制器名和操作名,所以实例化的时候把他们俩的名称也 // 传进去。结合Controller基类一起看 $dispatch = new $controller($controllerName, $actionName); // $dispatch保存控制器实例化后的对象,我们就可以调用它的方法, // 也可以像方法中传入参数,以下等同于:$dispatch->$actionName($param) call_user_func_array(array($dispatch, $actionName), $param); } // 检测开发环境 public function setReporting() { if (APP_DEBUG === true) { error_reporting(E_ALL); ini_set('display_errors','On'); } else { error_reporting(E_ALL); ini_set('display_errors','Off'); ini_set('log_errors', 'On'); } } // 删除敏感字符 public function stripSlashesDeep($value) { $value = is_array($value) ? array_map(array($this, 'stripSlashesDeep'), $value) : stripslashes($value); return $value; } // 检测敏感字符并删除 public function removeMagicQuotes() { if (get_magic_quotes_gpc()) { $_GET = isset($_GET) ? $this->stripSlashesDeep($_GET ) : ''; $_POST = isset($_POST) ? $this->stripSlashesDeep($_POST ) : ''; $_COOKIE = isset($_COOKIE) ? $this->stripSlashesDeep($_COOKIE) : ''; $_SESSION = isset($_SESSION) ? $this->stripSlashesDeep($_SESSION) : ''; } } // 检测自定义全局变量并移除。因为 register_globals 已经弃用,如果 // 已经弃用的 register_globals 指令被设置为 on,那么局部变量也将 // 在脚本的全局作用域中可用。 例如, $_POST['foo'] 也将以 $foo 的 // 形式存在,这样写是不好的实现,会影响代码中的其他变量。 相关信息, // 参考: http://php.net/manual/zh/faq.using.php#faq.register-globals public function unregisterGlobals() { if (ini_get('register_globals')) { $array = array('_SESSION', '_POST', '_GET', '_COOKIE', '_REQUEST', '_SERVER', '_ENV', '_FILES'); foreach ($array as $value) { foreach ($GLOBALS[$value] as $key => $var) { if ($var === $GLOBALS[$key]) { unset($GLOBALS[$key]); } } } } } // 配置数据库信息 public function setDbConfig() { if ($this->config['db']) { define('DB_HOST', $this->config['db']['host']); define('DB_NAME', $this->config['db']['dbname']); define('DB_USER', $this->config['db']['username']); define('DB_PASS', $this->config['db']['password']); } } // 自动加载类 public function loadClass($className) { $classMap = $this->classMap(); if (isset($classMap[$className])) { // 包含内核文件 $file = $classMap[$className]; } elseif (strpos($className, '\\') !== false) { // 包含应用(application目录)文件 $file = APP_PATH . str_replace('\\', '/', $className) . '.php'; if (!is_file($file)) { return; } } else { return; } include $file; // 这里可以加入判断,如果名为$className的类、接口或者性状不存在,则在调试模式下抛出错误 } // 内核文件命名空间映射关系 protected function classMap() { return [ 'fastphp\base\Controller' => CORE_PATH . '/base/Controller.php', 'fastphp\base\Model' => CORE_PATH . '/base/Model.php', 'fastphp\base\View' => CORE_PATH . '/base/View.php', 'fastphp\db\Db' => CORE_PATH . '/db/Db.php', 'fastphp\db\Sql' => CORE_PATH . '/db/Sql.php', ]; } }
下面重点讲解主请求方法 route()
,它也称路由方法。
路由方法的主要作用是:截取URL,并解析出控制器名、方法名和URL参数。
假设我们的 URL 是这样:
yoursite.com/controllerName/actionName/queryString
当浏览器访问上面的URL,route()
从全局变量 $_SERVER['REQUEST_URI']
中获取到字符串/controllerName/actionName/queryString
。
然后,会将这个字符串分割成三部分:controllerName
、actionName
和 queryString
。
例如,URL链接为:yoursite.com/item/detail/1/hello,那么route()
分割之后,
- ControllerName名就是:item
- actionName名就是:detail
- URL参数就是:array(1, hello)
分割完成后,路由方法再实例化控制器:itemController
,并调用其中的detail
方法 。
4.4 Controller基类
接下来,就是在 fastphp 中创建MVC基类,包括控制器、模型和视图三个基类。
在fastphp/base/
目录下新建控制器基类,文件名 Controller.php,功能就是总调度,内容如下:
<?php namespace fastphp\base; /** * 控制器基类 */ class Controller { protected $_controller; protected $_action; protected $_view; // 构造函数,初始化属性,并实例化对应模型 public function __construct($controller, $action) { $this->_controller = $controller; $this->_action = $action; $this->_view = new View($controller, $action); } // 分配变量 public function assign($name, $value) { $this->_view->assign($name, $value); } // 渲染视图 public function render() { $this->_view->render(); } }
Controller
类用assign()
方法实现把变量保存到View对象中。
这样,在调用$this->render()
后视图文件就能显示这些变量。
4.5 Model基类
新建模型基类,继承自数据库操作类Sql
类。
因为数据库操作比较复杂,所以SQL操作我们单独创建一个类。
Model
基类涉及到3个类:Model
基类本身,它的父类SQL
,以及提供数据库连接句柄的Db
类。
在fastphp/base/
目录下新建模型基类文件,名为 Model.php,代码如下:
<?php namespace fastphp\base; use fastphp\db\Sql; class Model extends Sql { protected $model; public function __construct() { // 获取数据库表名 if (!$this->table) { // 获取模型类名称 $this->model = get_class($this); // 删除类名最后的 Model 字符 $this->model = substr($this->model, 0, -5); // 数据库表名与类名一致 $this->table = strtolower($this->model); } } }
在fastphp/db/
目录下建立一个数据库基类 Sql.php,代码如下:
<?php namespace fastphp\db; use \PDOStatement; class Sql { // 数据库表名 protected $table; // 数据库主键 protected $primary = 'id'; // WHERE和ORDER拼装后的条件 private $filter = ''; // Pdo bindParam()绑定的参数集合 private $param = array(); /** * 查询条件拼接,使用方式: * * $this->where(['id = 1','and title="Web"', ...])->fetch(); * 为防止注入,建议通过$param方式传入参数: * $this->where(['id = :id'], [':id' => $id])->fetch(); * * @param array $where 条件 * @return $this 当前对象 */ public function where($where = array(), $param = array()) { if ($where) { $this->filter .= ' WHERE '; $this->filter .= implode(' ', $where); $this->param = $param; } return $this; } /** * 拼装排序条件,使用方式: * * $this->order(['id DESC', 'title ASC', ...])->fetch(); * * @param array $order 排序条件 * @return $this */ public function order($order = array()) { if($order) { $this->filter .= ' ORDER BY '; $this->filter .= implode(',', $order); } return $this; } // 查询所有 public function fetchAll() { $sql = sprintf("select * from `%s` %s", $this->table, $this->filter); $sth = Db::pdo()->prepare($sql); $sth = $this->formatParam($sth, $this->param); $sth->execute(); return $sth->fetchAll(); } // 查询一条 public function fetch() { $sql = sprintf("select * from `%s` %s", $this->table, $this->filter); $sth = Db::pdo()->prepare($sql); $sth = $this->formatParam($sth, $this->param); $sth->execute(); return $sth->fetch(); } // 根据条件 (id) 删除 public function delete($id) { $sql = sprintf("delete from `%s` where `%s` = :%s", $this->table, $this->primary, $this->primary); $sth = Db::pdo()->prepare($sql); $sth = $this->formatParam($sth, [$this->primary => $id]); $sth->execute(); return $sth->rowCount(); } // 新增数据 public function add($data) { $sql = sprintf("insert into `%s` %s", $this->table, $this->formatInsert($data)); $sth = Db::pdo()->prepare($sql); $sth = $this->formatParam($sth, $data); $sth = $this->formatParam($sth, $this->param); $sth->execute(); return $sth->rowCount(); } // 修改数据 public function update($data) { $sql = sprintf("update `%s` set %s %s", $this->table, $this->formatUpdate($data), $this->filter); $sth = Db::pdo()->prepare($sql); $sth = $this->formatParam($sth, $data); $sth = $this->formatParam($sth, $this->param); $sth->execute(); return $sth->rowCount(); } /** * 占位符绑定具体的变量值 * @param PDOStatement $sth 要绑定的PDOStatement对象 * @param array $params 参数,有三种类型: * 1)如果SQL语句用问号?占位符,那么$params应该为 * [$a, $b, $c] * 2)如果SQL语句用冒号:占位符,那么$params应该为 * ['a' => $a, 'b' => $b, 'c' => $c] * 或者 * [':a' => $a, ':b' => $b, ':c' => $c] * * @return PDOStatement */ public function formatParam(PDOStatement $sth, $params = array()) { foreach ($params as $param => &$value) { $param = is_int($param) ? $param + 1 : ':' . ltrim($param, ':'); $sth->bindParam($param, $value); } return $sth; } // 将数组转换成插入格式的sql语句 private function formatInsert($data) { $fields = array(); $names = array(); foreach ($data as $key => $value) { $fields[] = sprintf("`%s`", $key); $names[] = sprintf(":%s", $key); } $field = implode(',', $fields); $name = implode(',', $names); return sprintf("(%s) values (%s)", $field, $name); } // 将数组转换成更新格式的sql语句 private function formatUpdate($data) { $fields = array(); foreach ($data as $key => $value) { $fields[] = sprintf("`%s` = :%s", $key, $key); } return implode(',', $fields); } }
应该说,Sql基类是框架的核心部分。为什么?
因为通过它,我们创建了一个 SQL 抽象层,可以大大减少了数据库的编程工作。
虽然 PDO 接口本来已经很简洁,但是抽象之后框架的可灵活性更高。
Sql
类里面有用到Db:pdo()
方法,这是我们创建的Db
类,它提供一个PDO单例。
在fastphp/db/
目录下创建Db.php文件,内容:
<?php namespace fastphp\db; use PDO; use PDOException; /** * 数据库操作类。 * 其$pdo属性为静态属性,所以在页面执行周期内, * 只要一次赋值,以后的获取还是首次赋值的内容。 * 这里就是PDO对象,这样可以确保运行期间只有一个 * 数据库连接对象,这是一种简单的单例模式 * Class Db */ class Db { private static $pdo = null; public static function pdo() { if (self::$pdo !== null) { return self::$pdo; } try { $dsn = sprintf('mysql:host=%s;dbname=%s;charset=utf8', DB_HOST, DB_NAME); $option = array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC); return self::$pdo = new PDO($dsn, DB_USER, DB_PASS, $option); } catch (PDOException $e) { exit($e->getMessage()); } } }
4.6 View基类
在fastphp/base/
目录下新建视图基类 View.php 内容如下:
<?php namespace fastphp\base; /** * 视图基类 */ class View { protected $variables = array(); protected $_controller; protected $_action; function __construct($controller, $action) { $this->_controller = strtolower($controller); $this->_action = strtolower($action); } // 分配变量 public function assign($name, $value) { $this->variables[$name] = $value; } // 渲染显示 public function render() { extract($this->variables); $defaultHeader = APP_PATH . 'app/views/header.php'; $defaultFooter = APP_PATH . 'app/views/footer.php'; $controllerHeader = APP_PATH . 'app/views/' . $this->_controller . '/header.php'; $controllerFooter = APP_PATH . 'app/views/' . $this->_controller . '/footer.php'; $controllerLayout = APP_PATH . 'app/views/' . $this->_controller . '/' . $this->_action . '.php'; // 页头文件 if (is_file($controllerHeader)) { include ($controllerHeader); } else { include ($defaultHeader); } //判断视图文件是否存在 if (is_file($controllerLayout)) { include ($controllerLayout); } else { echo "<h1>无法找到视图文件</h1>"; } // 页脚文件 if (is_file($controllerFooter)) { include ($controllerFooter); } else { include ($defaultFooter); } } }
这样,核心的PHP MVC框架核心就完成了。
下面我们编写应用来测试框架功能。
5 应用
5.1 数据库部署
在 SQL 中新建一个 project 数据库,增加一个item
表、并插入两条记录,命令如下:
CREATE DATABASE `project` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; USE `project`; CREATE TABLE `item` ( `id` int(11) NOT NULL auto_increment, `item_name` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; INSERT INTO `item` VALUES(1, 'Hello World.'); INSERT INTO `item` VALUES(2, 'Lets go!');
5.2 部署模型
然后,我们还需要在app/models/
目录中创建一个 ItemModel.php 模型,内容如下:
<?php namespace app\models; use fastphp\base\Model; use fastphp\db\Db; /** * 用户Model */ class ItemModel extends Model { /** * 自定义当前模型操作的数据库表名称, * 如果不指定,默认为类名称的小写字符串, * 这里就是 item 表 * @var string */ protected $table = 'item'; /** * 搜索功能,因为Sql父类里面没有现成的like搜索, * 所以需要自己写SQL语句,对数据库的操作应该都放 * 在Model里面,然后提供给Controller直接调用 * @param $title string 查询的关键词 * @return array 返回的数据 */ public function search($keyword) { $sql = "select * from `$this->table` where `item_name` like :keyword"; $sth = Db::pdo()->prepare($sql); $sth = $this->formatParam($sth, [':keyword' => "%$keyword%"]); $sth->execute(); return $sth->fetchAll(); } }
因为 Item
模型继承了 Model
基类,所以它拥有 Model
类的所有功能。
5.3 部署控制器
在 app/controllers/
目录下创建一个 ItemController.php 控制器,内容如下:
<?php namespace app\controllers; use fastphp\base\Controller; use app\models\ItemModel; class ItemController extends Controller { // 首页方法,测试框架自定义DB查询 public function index() { $keyword = isset($_GET['keyword']) ? $_GET['keyword'] : ''; if ($keyword) { $items = (new ItemModel())->search($keyword); } else { // 查询所有内容,并按倒序排列输出 // where()方法可不传入参数,或者省略 $items = (new ItemModel)->where()->order(['id DESC'])->fetchAll(); } $this->assign('title', '全部条目'); $this->assign('keyword', $keyword); $this->assign('items', $items); $this->render(); } // 查看单条记录详情 public function detail($id) { // 通过?占位符传入$id参数 $item = (new ItemModel())->where(["id = ?"], [$id])->fetch(); $this->assign('title', '条目详情'); $this->assign('item', $item); $this->render(); } // 添加记录,测试框架DB记录创建(Create) public function add() { $data['item_name'] = $_POST['value']; $count = (new ItemModel)->add($data); $this->assign('title', '添加成功'); $this->assign('count', $count); $this->render(); } // 操作管理 public function manage($id = 0) { $item = array(); if ($id) { // 通过名称占位符传入参数 $item = (new ItemModel())->where(["id = :id"], [':id' => $id])->fetch(); } $this->assign('title', '管理条目'); $this->assign('item', $item); $this->render(); } // 更新记录,测试框架DB记录更新(Update) public function update() { $data = array('id' => $_POST['id'], 'item_name' => $_POST['value']); $count = (new ItemModel)->where(['id = :id'], [':id' => $data['id']])->update($data); $this->assign('title', '修改成功'); $this->assign('count', $count); $this->render(); } // 删除记录,测试框架DB记录删除(Delete) public function delete($id = null) { $count = (new ItemModel)->delete($id); $this->assign('title', '删除成功'); $this->assign('count', $count); $this->render(); } }
5.4 部署视图
在 app/views/
目录下新建 header.php 和 footer.php 两个页头页脚模板,如下。
header.php 内容:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title><?php echo $title ?></title> <link rel="stylesheet" href="/static/css/main.css" type="text/css" /> </head> <body> <h1><?php echo $title ?></h1>
footer.php 内容:
</body> </html>
页头文件用到了main.css样式文件,内容:
html, body { margin: 0; padding: 10px; font-size: 20px; } input { font-family:georgia,times; font-size:24px; line-height:1.2em; } a { color:blue; font-family:georgia,times; line-height:1.2em; text-decoration:none; } a:hover { text-decoration:underline; } h1 { color:#000000; font-size:41px; border-bottom:1px dotted #cccccc; } td {padding: 1px 30px 1px 0;}
然后,在 app/views/item
目录下创建以下几个视图文件。
index.php,浏览数据库内 item
表的所有记录,内容:
<form action="" method="get"> <input type="text" value="<?php echo $keyword ?>" name="keyword"> <input type="submit" value="搜索"> </form> <p><a href="/item/manage">新建</a></p> <table> <tr> <th>ID</th> <th>内容</th> <th>操作</th> </tr> <?php foreach ($items as $item): ?> <tr> <td><?php echo $item['id'] ?></td> <td><?php echo $item['item_name'] ?></td> <td> <a href="/item/manage/<?php echo $item['id'] ?>">编辑</a> <a href="/item/delete/<?php echo $item['id'] ?>">删除</a> </td> </tr> <?php endforeach ?> </table>
add.php,添加记录后的提示,内容:
<a class="big" href="/item/index">成功添加<?php echo $count ?>条记录,点击返回</a>
manage.php,管理记录,内容:
<form action="<?php echo $postUrl; ?>" method="post"> <?php if (isset($item['id'])): ?> <input type="hidden" name="id" value="<?php echo $item['id'] ?>"> <?php endif; ?> <input type="text" name="value" value="<?php echo isset($item['item_name']) ? $item['item_name'] : '' ?>"> <input type="submit" value="提交"> </form> <a class="big" href="/item/index">返回</a>
update.php,更改记录后的提示,内容:
<a class="big" href="/item/index">成功修改<?php echo $count ?>项,点击返回</a>
delete.php,删除记录后的提示,内容:
<a href="/item/index">成功删除<?php echo $count ?>项,点击返回</a>
6 应用测试
这样,在浏览器中访问 project程序:http://localhost/item/index/,就可以看到效果了。
以上代码已经全部发布到 github 上,关键部分加了注释:
要设计更好的MVC,或使用得更加规范,请看《MVC架构的职责划分原则》。
参考资料:
« Linux Nginx服务器搭建SSL/TLS(https+http/2) PHP函数include include_once require和require_once的区别 »
运营报错了。
Warning: mysql_num_fields() expects parameter 1 to be resource, boolean given in D:\phpStudy\WWW\fast\fastphp\Sql.class.php on line 60
Warning: mysql_fetch_row() expects parameter 1 to be resource, boolean given in D:\phpStudy\WWW\fast\fastphp\Sql.class.php on line 66
Warning: mysql_result() expects at least 2 parameters, 1 given in D:\phpStudy\WWW\fast\fastphp\Sql.class.php on line 72
应该是数据库连接不上导致的,把 $this->_dbHandle = @mysql_connect($address, $account, $pwd); 这一句中的 @ 去掉,可以显示具体错误。
怒赞
不错,很原始的设计。
为啥不用composer
目前只仅为了说明原理,用composer就复杂了。以后完善了再composer
作者牛逼 喜欢作者的开源分享精神 点赞
你好 教程写的很好,是我看过最良心的MVC框架介绍了,请问是否有兴趣继续把这个框架写下去,建议把mysql用mysqli,然后加一下路由,可以一步步慢慢扩展开来。还有文章里有个问题就是,你建的table有错误,itmes该为item就可以正常使用了,上面那位兄弟就是这个原因。
非常感谢你的建议,我们会每隔一段时间优化这个框架,谢谢!
model 中怎么调用操作sql的方法 😀
因为model继承了Sql类,所以直接用$this调用,例如:
写的很不错
我看了你的框架
很适合用在中小型 的 网站
上手快速
只是里面我有更改了一些东西
除了 MVC 之外 我有加入一个Helper 的基类 然后延伸Pagination / Upload / Validation 那些逻辑
这个类 主旨是能够重用
还有加入了 不同用户的权限 限制
例如User 只能用到 User的 controller
我对你的框架很有兴趣 如果可以的话 请email我 讨论一起发展下去?
优秀的Jacky
您好:
我是新手, 也在弄个内部用的网站, 您说有扩充了一些用户权限的功能, github上有链接吗,
想学一下, 这里是个小公司, 想弄个权限的模块
之前的 $_GET =stripSlashesDeep($_GET );我改成了 $_GET =$this->stripSlashesDeep($_GET );不然会报错,是不是我php版本造成的,我是一个新手。不太懂这个,然后访问根目录有报如下错误。
Fatal error: Class 'IndexController' not found in E:\apmserv\APMServ-v5.2.6\APMServ5.2.6\www\htdocs\fastphp\fastphp\Core.php on line 47
请问这个是什么原因造成的?
如果用 PHP5.2.6,就会有这个问题的,请使用 PHP5.4.0+ 。如果测试环境是Windows,可使用 phpStudy 来搭建环境,能切换多个版本的PHP。
PHP 7.0.6 也出現這個 是一個原因嗎?
请问具体的提示是怎样的呢?
使用php5.4,测试成功。很需要这种简单的原生的mvc,用于简化学习。非常感谢!
你好,最近在写基于MVC的php框架的论文,看了你写的对我有很大的帮助,在此表示感谢。如果加上一些思想的讲解,比如模型层引用的PDO等等。
谢谢 不错的教程.易懂适合我这样的菜鸟学习。 😆
首先谢谢博主的分享,让我学到了很多东西、我现在不解的是 ,(URL链接为:project.com/item/view/1/first-item $controller 就是:item $action 就是:view)是在哪个部分执行到了 index.php 为什么不用写project.com/index.php/item/view/1/first-item 就能引用到框架类库
在.htaccess文件中有这么一行:
作用是重定向请求到:index.php?url= 。
例如:当我们请求<域名>item/index时,实际上是请求<域名>index.php?url=item/index。在PHP中用
GET['url']
就能拿到字符串item/index
,请看Core.php中的Route()
方法。明白啦 谢谢博主 😈
😀
博主你好!这个$_GET['url']我查了好多资料,还是没搞清楚是什么意思。这个url参数是php本身就有的,还是您在哪里定义的?
文件.htaccess中有这样一句:
例如,当访问了:
www.awaimai.com/a/b
,传到PHP获得的地址就是:www.awaimai.com/index.php?url=a/b
,用$_GET['url']
就能得到字符串a/b
了明白了 谢谢博主!
博主你好 我是初学者 我看了你的框架 感觉帮助很大 谢谢
非常荣幸能够帮上忙 ,欢迎多多光顾:)
我的数据库是MSSQL,配置文件要怎么改
MSSSQL需要修改Sql.class.php文件中的PDO连接,如下一行:
改成MSSQL连接方式。
Notice: Undefined variable: items in E:\Apache\htdocs\project\application\views\item\index.php on line 9
Warning: Invalid argument supplied for foreach() in E:\Apache\htdocs\project\application\views\item\index.php on line 9
报错额,
说明没读出数据库里面的数据,需要调整Sql.class.php中点fetchaAll()等方法。
建议先用MySQL调通之后再换MSSQL。
我换成mysql,还是这错误
我在用你框架的时候出现了控制器找不到的错误,怎么解决呢?
用的github的代码么?可否把错误贴出来呢?
Fatal error: Class 'ItemController' not found in E:\web\WWW\mvc\fastphp\Core.php on line 45
是这样的,我把你的代码从网站上复制下去,打开就是这样,能够告诉我是哪里出问题了吗?
建议直接从github上clone一份
可能是大小写的问题
少了个路由,希望这个能加上去,还有少了个加载自定义类库的方法.
嗯,感谢提议!目前在Core.php文件的route()方法中,有做简单点路由处理呢 🙂
我找不到Core.php文件……
新版已经改为Fastphp.php文件了。
博主可以问一下吗?ItemController里面没有调用方法给 content赋值,为什么可以显示view 里面相应的content内容呢?比如 views/item/index.php 、add.php
在View基类中,有两个方法:
assign()
和render()
。assign()
将变量保存到variables
数组中,render()
输出变量,在之后用include
包含方式显示。你好,可以问个问题么。$dispatch = new $controller($controllerName, $action);里面的$controllerName, $action是怎么传过来的
通过URL传递过来的。
为什么的的评论一直显示排队审核中。。。
楼主楼主,这个情况该怎么解决, /home/u980175229/public_html/ 是我的php空间的目录, php版本 5.5
Fatal error: Class 'IndexController' not found in /home/u980175229/public_html/fastphp/Core.php on line 45
应该是复制代码有缺失导致的,建议直接通过github克隆代码。
连接oracle 所有sql语句都要改
只需要改Sql类就可以了。
博主你好,我是一个初入门的PHP新手,之前学习了PHP的基础知识,然后又学习了一些网站项目的功能实现,都比较简单.这是第一次接触到MVC这个概念,按照您的教程做,发现绝大多数代码都不懂其含义,也出现了很多即便是查资料也一知半解的函数.我本来想针对于几个特别难懂的点问您,后来发现不懂的太多了,没可能一个一个问,所以想请问您,有什么更好的方式能使我这种新手更有助于理解的方法吗? 一些其他的相关知识? 书籍? 我想也许是我的基础知识底蕴还不够,可是我不知道涉及到这篇文章需要了解哪些知识,总之,希望能获得您的帮助,感激不尽!
嗯,可能还是需要扎实一下基础,一些PHP语法用法的数据都看一下吧。
书籍推荐可以参看这里:https://github.com/yeszao/phproad。
请问一下:
public function add()
{
$val = !empty($_POST["value"]) ? $_POST["value"] : "没有获取到文本值";
$data['item_name'] =$val;
为什么$_POST["value"] 获取不到值呢?
检查一下PHP环境。
// 添加记录,测试框架DB记录创建(Create)
public function add()
{
var_dump($_POST);die;
$val = !empty($_POST["value"]) ? $_POST["value"] : "没有获取到文本值";
是个空数组,这是什么问题呢?
检查一下PHP环境,代码测试过OK。
博主你好,非常感谢你的分享,我这里有个问题,你在Core.php文件中的route路由处理方法中,有那么以下两句:
// 实例化控制器
$controller = $controllerName . 'Controller';
$dispatch = new $controller($controllerName, $action);
我想问一下,$dispatch = new $controller($controllerName, $action);这一句代码,我看你好像也没有引进什么文件啊,这样实例化类会报错吧,而且我运行的时候也报错了:Fatal error: Class 'ItemController' not found in F:\wwwroot\myframe\fastphp\Core.php on line 44
不需要手动
include
的,用spl_autoload_register(array($this, 'loadClass'));
就可以实现通过loadClass()
方法自动加载类文件。如果报错,请确认PHP为5.4+版本,建议从github下载最新的代码。
嗯嗯,刚刚走了一遍这个代码,基本上可以理解了。非常感谢
我知道了,那个控制器的文件名应该为ItemController.class.php,而不是ItemController.php
您好!歪麦,我是从phpchina获得此教程,然后过来学习的,近期有意向自己写程序,搞个轻论坛,但鉴于现时的轻论坛项目过于同质化,某些RUBY些的,或者基于laravel框架的一些程序,对我来说又难以部署和维护,所以想零基础学习PHP+MYSQL,结合一些前端框架,比如BOOTSTRAPE,编写一套功能相对简单,但完全符合自己期望的轻论坛,现在经您介绍,对于MVC架构的开发工作有了较详细的了解,但对于字符的入库和出库处理,还是比较朦胧,不知您是否有空闲可以略作介绍?如果可以,真是非常感激。再次感谢你的教程,这对初学者帮助非常大!
字符的入库和出库是否指的是数据库的增查改删(CRUD)?
这个在我们的框架中也有的哟,就是Sql类,增查改删都有的,用的是PDO类来读写数据库。
如果不理解,可以详细看看PHP网站PDO的介绍。
你好,可能是我表述得不够好,我想请教的可能是关于转义方面的问题?在具体一点,假如现在我要开发一个轻论坛,那么用户发帖时的内容里面,如果含有换行、空格、甚至HTML标记、代码等,我应该如何对危害数据库/程序安全的字符过滤?如何对换行、空格等正常入库,而查的时候又能正常恢复其原有行为格式?歪麦可以给点思路吗,谢谢。
使用PDO的预处理语句就可以基本解决:http://php.net/manual/zh/pdo.prepared-statements.php
PHP网站也对SQL注入有介绍:http://php.net/manual/zh/security.database.sql-injection.php
收到,谢谢你!
很不错的PHP文章,从头开始设计PHP框架。
博主,请问fashphp目录下的那些类怎么引进去的啊?比如sql.class.php等
loadClass方法实现类加载,再用PHP的spl_autoload_register方法自动加载
请教博主, 检测自定义全局变量(register globals)并移除,这段代码的具体作用是什么,可以举个例子吗?谢啦
因为
register_globals
已经弃用。如果已经弃用的
register_globals
指令被设置为on
,那么局部变量也将在脚本的全局作用域中可用。例如,
$_POST['foo']
也将以$foo
的形式存在,这样写是不好的实现,会影响代码中的其他变量。相关信息,参见 FAQ “register_globals 对我有什么影响?”
这哪里是参考!!
完全就是翻译!!!!!
😀
Controller类中初始化里有下面的一条语句
$this->_view = new View($controller, $action);
哪个地方包含了View.class.php文件?之前没有系统说过php,房主解答下。
Core.php中用PHP提供的
spl_autoload_register
方法实现了类文件的自动加载,具体实现在:loadClass
方法中。详细请看PHP官网介绍:http://php.net/manual/zh/function.spl-autoload-register.phpphp 5.4+ 版本的,你的框架好像没有对特殊符号转义呢
各种数据都有自己不同的用途,在入口对数据一刀切地进行转义,这种方式并不优雅,还有可能带来不必要的麻烦。
所以PHP5.4+取消了这个功能。
详情可看PHP官网解释:http://php.net/manual/en/security.magicquotes.php
缺陷是一个model不能调用其他model
可以的
请问博主nginx服务器怎么配置 .htaccess 文件呢?
public function where($where = array())请问这个方法是用来干麻的?看不懂
拼装MySQL的WHERE条件
博主,有没有 Model 传递记录给 Control 的Demo?一次性传递多条数据的
额。。。不太明白,能否详细描述详细一点呢
楼主请教下, autoload 自动加载里 用 require require_once include include_once 有什么区别么?网上看大家各种写法都有。找资料找半天也没找到
这几个函数是有区别的,require遇到警告时更严厉,include则比较宽松。具体请看另一篇文章:PHP函数include include_once require和require_once的区别
楼主你好,请教一下:假如我访问www.awaimai.com 让其指定默认的控制器和操作为 site/index 就是www.awaimai.com/site/index 等于www.awaimai.com
楼主你好,请教一下:假如我访问www.awaimai.com 让其指定默认的控制器和操作为 site/index 就是www.awaimai.com/site/index 等于www.awaimai.com
办法是,修改Core.php文件,将route()方法中的
$controllerName = 'Index';
和$action = 'index';
的值改为需要的内容。我的意思是能不能不加/site/index 这种,然后直接访问网址www.awaimai.com就能访问到www.awaimai.com/site/index,
我现在如果不加控制器名和方法名就会报错
懂了!谢谢
好的
兄弟 请问你接不接私活
这个嘛,私聊啦 🙂
楼主请问一下,,我想做前后台,该怎么实现,目前我只能做一个前台,要怎样分出后台应用
暂时没做分模块呢,如果要做前后台,加上模块支持就可以啦
这是我见过的最好的PHP MVC入门教程了,感谢博主 😀
已小额赞助,多写些经典的 ❗ ❗
也是Fatal error: Class 'IndexController' not found in D:\phpStudy\WWW\demo\todo\fastphp\Core.php on line 44 这个错
最后发现是路径少了个杠:D:\phpStudy\WWW\demo\todo/application/controllersIndexController.class.php 😈
你如何解决的呢?
在Core.php的loadClass方法中:
$controllers = APP_PATH.'application/controllers' . $class . '.class.php';
这句controllers后面少了个斜杠:
就是这样:$controllers = APP_PATH.'application/controllers/' . $class . '.class.php';
很细节的地方 🙄
Fatal error: Uncaught Error: Class '/ItemController' not found in D:\projects\aureview\frame\Core.php on line 45
( ! ) Error: Class '/ItemController' not found in D:\projects\aureview\frame\Core.php on line 45
有没有额外说明?
目录结构都和教程的一样。
fastphp -
- Controller.class.php
- Core.php
- fastphp.php
- Model.class.php
- Sql.class.php
- View.class.php
ItemController.php在application > controller目录下
直接git clone代码是否有同样问题呢?
我是顺着教程走下来的,和你的github的项目比较了一下发现你的教程里说的不一样,比如教程里没说views目录下还有一个layout.php。教程里说的ItemController.php其实不对,你的项目里的是ItemController.class.php。另外教程里也没提到还有一个文件叫做IndexController.class.php,我补充上文件并且改名之后就没问题了。
好的,问题已修复并优化了框架。
网址上输入localhost/fastphp 之后,,,提示Controller控制器不存在,,这是什么原因呢?
把localhost的站点目录设置为project目录,然后直接访问localhost呢?
我如果想在数据库塞一些分类,比如按地域分,比如beijing。然后点击domain/beijing,正常会出现错误 Fatal error: BeijingController not found。 这个分类肯定不能是由一个地区就写一个controller的吧,那还不累死,而且内容都相同,肯定是调阅比如数据库跟这个地区挂钩的比如食物数据,人员数据等等。这样的话应该大概怎么写,能不能给点思路,谢谢。
我在php7.1.2下调试提示有几处语法错误,可能是php7.1.2语法要求更规范的原因。例如在类属性成员定义出现语法错误:protected $_config = [];应修改为protected $_config = array();还有:(new Fastphp($config))->run();修改为:$runFrame = new Fastphp($config);$runFrame->run();
现在的问题是:语法修正后调试出现"Controller控制器不存在",麻烦帮忙解决下。
我试了PHP7.1.4,没有出现这样的提示呢
PHP7中也是可以用[]代表数组的,提示控制器不存在可能是代码有遗漏。
请从github上克隆一份再试试。
谢谢热心指导,我刚下载xampp7.1.4默认设置安装和从githib上重新克隆,在未编辑代码情况下,程序可以运行,但仍然把报“Contrpller控制器不存在”的提示,请问是不是我的php服务器设置不对?叧外关于语法错误的问题,我用的是dreamweaver cs6。早上提的语法错误还是有,只是不影响程序运行。打开文件有:此页可能具有仅可由服务器搜索到的动态相关文件,点击“搜索”就提示:语法错误
那是可以运行呢,还是报错呢?我在apache和nginx服务器下都试过呢,似乎都没有出现类似的问题
最好查一下apache的log日志,查找一下具体原因
一般来说,这种直接通过表单提交的,用一个控制器就可以了。
比如创建一个area的控制器、一个area的model。
控制器负责接受处理表单数据,area负责读写数据库。
假设要插入beijing这个分类,就可以在表单里面用一个input/select等HTML标签定义,提交后发给控制器。
控制器再传给model写入数据库,这样就可以了。
关于表单那个,网上有现成的例子吗,或者说我要想搜索例子的话用什么关键词比较准确?
可以看看这个是否符合:http://www.runoob.com/php/php-forms.html
还是跟着我之前询问的地域那个问题,我自己创建了一个region的controller和index的view,但是现在遇到了一个思路上的问题。假设路径会是region/beijing或者region/shanghai,这样的话我是不是要为每个地点都建立一个class,但是它们其实内容都差不多。有没有办法只创建一个class,然后用户访问region/beijing的时候,去数据库的region表找有没有beijing,如果有就显示beijing的内容,没有就显示没有该地名
也不一定都创建控制器呀,像这种:
这样不是也可以吗?
理解了,但是用这样的方式可以写成region/Beijing吗?
region是控制器,beijing是操作名,在控制器里面增加一个操作就可以了
参数也可以做成这样:region/view/beijing,只要路由里面规定好就行
歪麦,我是刚学php的新手,我有个疑问,每个控制器都要继承Controller基类,但这个Controller基类是什么时候引入进去的?
Fastphp.php里面的run()方法注册了自动类加载
spl_autoload_register(array($this, 'loadClass'));
因为子类继承了父类,所以PHP会去根据loadClass()方法去寻找该父类文件,并include进来。
可以研究下PHP的类自动加载。
我发现model里面没有任何例子,能增加一个简单的model的例子吗
感谢建议,已经加上了
Not Found
The requested URL /item/add was not found on this server.
报了这个错,是我有哪儿没有配置吗? 🙄
应该是.htaccess文件没配置好,或者nginx的跳转未配置。
作者能简单的解释一下
spl_autoload_register( array( $this, 'loadClass' ) );
$this->setReporting();
$this->removeMagicQuotes();
$this->unregisterGlobals();
$this->route();
调用本类中的方法,每个方法都有独自的注释说明的,请往下看。
"如果文件或者目录真实存在,则直接访问存在的文件/目录。比如,静态文件static/css/main.css真实存在,就可以直接访问它。"
问题:project/application/下的MVC以及config等也是真实存在的文件和目录,也是可以直接访问的吗?如果使用rewrite规则将请求全部重定向到index.php,根据楼主Apache(Nginx)的配置,并未对静态文件和php脚本区分开来,只是用存在与否进行区分,可是如果直接访问php脚本呢
如果直接访问,也可以,但是因为没有
echo
等输出语句,所以看到的是空白的。如果访问的是控制器、或者model、或者其他核心类,因为是类,没有指明方法名也是没有输出的。
如果要安全一点,那就在每个头加上这样一句:
没有从index.php走的访问一律提示无权限。
赞同,因为框架MVC或config一般不会直接echo输出,所有直接访问是空白。在每个头上加上这句,也是保证安全,同时需要新增一个index.html(Access Denied)文件放在每层目录中,防止文件和目录被攻击者一览无余~类似于CI。还有一种比较好的方法就是在Nginx或Apache中配置location:涉及静态文件(.css/.js/.jpg等)可直接访问,涉及到php脚本全部重定向到index.php入口文件
同意!
LzController鎺у埗鍣ㄤ笉瀛樺湪,楼主,这是地址错误?
乱码呢?
一直说控制器不存在是什么情况
是我访问http://localhost/lz/indexphp错了,才会一直说控制器不存在。
Not Found
The requested URL /lz/Item/index was not found on this server. 又出现新问题了
为啥中间多了个
lz
?最好配个域名,访问就很顺利了。。LZ 应该是他自己的项目名字 相当于博主的project
相同的错误,连乱码都一摸一样
http://localhost/fastphp-master/
报错:app\controllers\Fastphp-masterController鎺у埗鍣ㄤ笉瀛樺湪
是在您的github拷贝的源代码
要配置源码为网站根目录
一直报控制器不存在怎么办
那就是确实没有这个控制器,或者nginx配置:
有个地方要更正一下,要把 application/views/ 下的 item 改成 Item(大写),否则报错:Warning: include(/home/*/*/project/application/views/Item/index.php): failed to open stream: No such file or directory in /home/*/*/project/fastphp/View.php on line 41
因为,你在用程序 将 item 的首字母大写了,如果不改 那就找到不文件夹喽! 调试了半天,才发现~
还有这个程序的效果是什么?只有 全部条目,管理条目?但是 添加了 ,也没见到添加到哪里了?
嗯,如果系统是Linux,因为大小写敏感,确实会存在这个问题 。
已经修改了,views下面的目录和文件全部用小写。
另外,添加条目了之后,在“全部条目”下是可以看到新增的记录的。
这个真心没有,全部条目 -》 新建 -》 管理条目 -》点击添加以后 -》成功添加0条记录 返回 -》 跳转到 全部条目 -》然而没看任何记录
说明数据库没写成功
我在View.class.php里面修改了这行 public function render( $codec = 'html' ) 然后在我自己的MyController 里面的index()调用的时候用了$this->render( 'json' );就报错说我那个render() 有missing 1 argument
Controller.php里面还有用了View对象的方法,
一般像你这个情况,建议重新加一个方法,请参看面向对象设计原则的开闭原则。
ProjectController.php不存在
确实没有这个控制器的,要自己创建,默认有`ItemController`
你这好多坑啊!
比如哪里?
解决啦,你网上的代码,和github上的有区别,问题解决!
OK,可能更新的时候有遗漏,再同步下。
不明白为什么model类为啥要继承SQL,为什么不通过一个SQL实例来操作数据库。
域名/item/manage/1这个编辑或者新建或者删除会报The requested URL /item/manage/1 was not found on this server.这种错误
需要配置一下Nginx或apache
是配置apache的伪静态这一块吗?可是我配置的是打开的啊
这里有介绍:3.3 重定向设置
那请问如何配置这一块的Apache呢,我找了百度很多配置Apache的东西都没搞定,能和你细聊吗?qq1396930993
缺的那个控制器直接复制 ItemController.php重名命可以吗? http://localhost/fastphp/item/index.php 打开提示“item方法不存在”。 新手第一次接触php的MVC,帮忙回答一下。
如果Nginx或者apache配置好的话,直接访问localhost就可以了,建议从github上克隆最新代码。
刚开始学习写mvc框架,博主的文章太有用了。我有一个问题,我运行代码时提示:
Notice: Undefined index: db in D:\xampp\htdocs\test\fastphp\Fastphp.php on line 119
TestController控制器不存在
能帮我看一下那里写错了吗?
重新配置一下文件:config/config.php,具体请看:3.5 配置文件
我现在 有一个 疑问 $this->_view->render(); $this->_view->assign($name, $value); 这两个 是将什么值 存入 这里的呢
render()不需要传入参数,assign()在控制器里面传入参数
你好,请教一个细节问题。fastphp里有个spl_autoload_register函数,然后我发现其实在如下两行就会触发:
$controller = $controllerName . 'Controller';
if (!class_exists($controller)) {
此时$controller是ItermController的,那么是不是就无法正常加载 $models = APP_PATH . 'application/models/' . $class . '.php';Model类了,另外还有 $frameworks = __DIR__ . '/' . $class . '.php';也不清楚是干嘛用的,还请指导,谢谢!
我大概理解了,需要把所有可能性考虑进去,找到了调用点了 Model:: 还有extends Controller之类的。。。谢谢!
学完了,感觉还可以简单明了~
打算下午自己写一遍,加固下~
嗯,加油:)
就是类的自动加载,PHP提供有现成用法的。
这么封装应该怎么实现前后台分离呢? 😕
前后台分离需要路由的支持,我们这个教程主要用来学习的,所以这一块目前暂时未考虑加呢
前后分离,你该说,返回数据即可(比如json),而不是返回网页。。。
挖僵尸了。。。
哈哈,两种理解方式~
在sql.class.php里为什么要用 return $this
主要是为了链式操作。
楼主好:
php集成环境wamp,代码是博主GitHub上下载的,全部代码放在wamp/www/project文件夹内,地址栏:localhost/project/item/index 报错:projectController控制器不存在 请问在该环境下如何正常运行该项目?
看了 楼主写的 这个 mvc ,整体感觉 还是能学到一些不错的思想
但是出现的安全问题就是application 下的model 层处理search 出现了 sql注入, 没有进行占位符的处理 导致PDO 一样是拼接字符串
导致sql注入 payload => keyword=1%' and (sleep(8)) --+ 简单的方法就是使用sqlmap 跑一下就能发现是可以进行注入的
嗯,一般项目中必须使用占位符预处理,不然注入风险很大。
github上是最新的代码,要不你帮忙提交个pull request,我合并到主干上?
如果把代码直接放在wamp/www目录下呢?我猜应该是多了一个目录。
Fatal error: Class 'Model' not found in D:\phpStudy\WWW\shiyue\wuli_s\fastphp\Fastphp.php on line 130
这个有点问题
D:\phpStudy\WWW\shiyue\wuli_s\这个目录是否是站点的根目录呢?
如果不是,那需要配置一下phpStudy,把这个目录作为站点根目录。
楼主好,
我正在学习php的mvc,楼主的代码对我帮助很大。
我现在有一个问题,如果我要使用ajax,比如校验用户名密码,在登录页直接反馈结果,请问使用您的这个框架怎么实现呢?
我之前是直接使用如下代码:
$.post("login.php",pars,loginFeedback);
function loginFeedback(data){
if(data=="success")
window.location.href="index_frame.php";
else
$("#error").html(data);
}
可以的呀,把请求地址改成相应MVC中的地址就可以啦,比如:
$.post("/item/manage/1", pars, loginFeedback);
这样就会提交到Item控制器的manage方法中。
出現了一個問題
Parse error: syntax error, unexpected 'count' (T_STRING) in /home/coolca11/public_html/application/controllers/ItemController.php on line 29
变量名写错了吧
我似乎看到了一个喜欢拍黄片的大佬博客,
/捂脸
你好,假设我访问的是:`http://xxxx.com/api/news/list/55`,我要在 `application\views\api\news.php` 获取 `list/55` ,需要怎么写呢?反复看了 `fastphp\Fastphp.php` 路由那块的注释,依旧没搞懂,望指点下。
看Fastphp.php里面的route()路由方法,参数list/55会传到控制器的参数。
怎么自动加载基类的class.php文件的,我看自动加载函数中没有加入进去
在Fastphp.php框架核心的loadClass()方法里面,使用了PHP的类自动加载功能。
Parse error: syntax error, unexpected T_OBJECT_OPERATOR in C:\AppServ\www\project\index.php on line 15
怎么一访问就出现这个问题,文件我都没有动过,数据库都搞好的了……
要用PHP5.4+
博主,首先谢谢分享啊。
我一直提示控制器不存在,我是WampServer64装的环境,php5.5.12,apache2.4.9,还需要怎么设置吗?我别的项目是可以正常运行的。看到给回复一下哦,万分感谢。
自己写的控制器吗?请确保配置apache的站点目录根目录为index.php所在目录。
apache的站点根目录为index.php所在目录,照样提示控制器不存在。我下了你的git的代码,除了改数据库连接,其它没改,不知是环境还需要怎么配置?
是的,改数据库配置,同时设置apache(或nginx)就可以了的。
博主,我也是个PHP新手,看了基础知识,就上手你这个了,发现按照你网页的打代码无法运行,又从你的GitHub下载了代码,运行发现还是不行,主要应该是Fastphp.php这些有问题的。访问http://localhost/project/application/views/item/index.php,报出http://localhost/project/application/views/item/index.php。同时view.php并没有组装好html,所以出现乱码等等。。。所以想请教一下,有没有debug模式,我好一步一步自己看,我是用phpstudy搭建环境的。。
。。。需要创建一个站点,根目录为project所在的目录。
版主您好
首先
謝謝 教導 此篇對我學MVC真的很有幫助
以下為問題點所在
網址上輸入localhost / fastphp之後,,,提示Controller不存在,
是否能請教一下
我是用wamp 開啟 www底下想要分資料夾
我已看過您的解釋,因為我不想設置根目錄 有辦法解決嗎?
我試過更改您的路徑無法解決 所以才想問看看您的想法
我是新手 所以對MVC有不懂的地方 請多多包涵
你好,如果不设置根目录,那就需要调整代码了呢
因为在route()方法里面我们是根据“/”来读取参数的
所以不设置根目录可以通过修改route()方法来适配
你好,请问class ItemController extends Controller 是如何定位到Controller的?
类自动加载呀
class ItemController extends Controller这个怎么实现类自动加载呀,具体的代码是哪些?
在Fastphp基类里面,详细请看上面几楼的回复。
博主,首先谢谢分享,让我复习了一遍MVC框架。
我想要说的是:能简单介绍自动类加载,也就是这个是干嘛用的,我不是想了解这个的具体实现,或许我连我自己想了解什么都不知道
从index.php进入,如何能进到view 下的index.html页面啊!
流程大概是:index.php → Fastphp.php → ... → XXXController → view/XXX.html
跟踪代码更清晰些
博主写的确实不错,可惜代码没有namespace部分,我现在需要学习带有namespace的自编框架,仍然感谢
嗯,现在namespace确实是趋势,有空了整理下
如果你有修改,提交个pull request到github上一起看看
博主人好热情!哈哈~~
感谢博主给出这么好的MVC教程!
我的也报错,说Model类没有找到,尴尬
Fatal error: Class 'Model' not found in D:\3W\project\fastphp\Fastphp.php on line 136
看了楼上,博主的回答,是不是必须要把站点的根目录设置为项目的根目录呢?
我还是菜鸟,勿怪 ~
嗯,是必须的。
还有啊,博主能给个联系方式吗?
昨天看到另外一篇MVC模式介绍的时候碰到的问题,百度了一下午,没找到解决办法,想谷歌去,还无法翻墙。
SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES)
好难受哇 ~
数据库无法连接,估计是配置或者权限问题。
联系方式在“关于”页面
db类是如何引入的,我没看到继承进来。$sth = Db::pdo()->prepare($sql); 这里没继承是如何调用的pdo()方法的?
Db::pdo()是静态方法,静态方法可以直接使用的,不需要继承,也不需要实例化。
引入的话,是通过类自动加载引入的。
您这个代码应该不完整吧。
views/item/index.php中跳转到detail.php时候,变量是传不过去的
detail.php中下面这两行代码运行是错误的:
ID:
Name:
是可以的哟,或者直接从github上下载代码试试
有QQ吗,加你QQ聊。 我这个地方不是很明白,我的代码运行不了。
QQ在关于页面有哦
手把手的话,我选择女老师
很好,已经讨论到12月了,首先非常感谢博主的无私贡献,才有了我们方便的基础入手,现在问题来了,楼上有人jacky提到过加入了:Pagination / Upload / Validation 这几个基类,楼主能不能完善下去?这个很急需哦,又或者弄个开放平台,可以一起搞大这个框架。谢谢,各位辛苦了。
代码全部放在github上了呢,大家都可以修改提交的哦~~
请问nginx配置中try_files $uri $uri/ /index.php$args; $args不是url传的参数么,前面只加一个index没有吧$url带上是不是路由就拿不到了,还是路由拿信息是通过$_SERVER全局变量,所以就不需要/index.php后面带上路径信息了?
出现这种错误是哪里出错了?
Notice: Undefined index: id in /data/home/qxu1192210031/htdocs/app/views/item/index.php on line 16
并且只能新建两条数据,新建第三条的时候就显示已新建0条数据
这个框架教学太棒了,刚刚入门,看完这个以后整个框架结构思路就出来了。立即自己写了一个,收获很大。
然后试着读了别的MVC框架,貌似瞬间清晰了很多,简直打开了新世界的大门。
收藏了√
PHP MVC框架入门经典
希望有空能继续维护。博主啊您这个博客很有价值,抵得上几本书!
哈哈,过奖了,感谢支持~
在manage.php中表单的提交地址是$postUrl的值:
<form action="" method="post">
但是我找遍全篇也没找到给$postUrl赋值的语句,这就导致了那个提交的按钮怎么按也没有用。。。
个人认为应该在ItemController.php的manage function中添加如下的赋值语句:
if ($id == 0) // create new item
{
echo "item id is ".$id;
$this->assign('postUrl', 'add');
}
else // update existing item
{
echo "item id is ".$id;
$this->assign('postUrl', '../update');
}
这样提交按钮就有效了。。
以github代码为主哟,都有详细注释的
博主你好,对于php编程我还是个新手。spl_autoload_register('auto_load_function') 这种syntax我能够理解,但是spl_autoload_register(array($this, 'loadClass'))这个就不容易理解了,这里的 array($this, 'loadClass') 是创建了一个array吗?含有$this 和 'loadClass' 两个元素的array?这说不通啊?在网上找了很久也没有答案,希望博主或其他朋友不吝赐教。
如果有个全局函数auto_load_function,那么我们可以用:spl_autoload_register('auto_load_function')
但是如果这个变量是在本类里面,就得用spl_autoload_register(array($this, 'loadClass'))这种方式了,告诉spl方法我用的是本类的方法,而不是全局函数。
因为我们总不能这样传入:spl_autoload_register('$this->loadClass'),或者:spl_autoload_register([$this=>loadClass]),
前者会被当成一个完整的字符串,去找名为'$this->loadClass'的全局函数,后者语法错误。
换个角度来理解的话,就是,spl_autoload_register支持传入字符串和数组,如果是字符串,那直接调用这个方法,
如果是数组(假设为:$a),就以对象方式调用,即:$a[0]->$a[1],这里就是$this->loadClass。
PHP官网有个Note有提到:http://php.net/manual/en/function.spl-autoload-register.php#102180
博主解释的好详细,再次感谢!我在根据您MVC框架的启发搭建符合我自己项目需求的框架。现正在研究.htaccess的语法中。祝博主和各位朋友圣诞及新年快乐!
祝你元旦快乐啦,哈哈
歪麦你好,nginx环境中当域名是www.mvc.com/index/demo 可以重定向到入口文件那
当域名是www.mvc.com/index/demo?id=1 就是file not found
问题是:这一块重定向该怎么写? 当时你的是什么环境?
可以直接用
www.mvc.com/index/demo/1
这种方式。你好,Controller 为什么不用单例呢?
因为一次请求只会实例化一个Controller,而Model层可能多次被Controller调用。
谢谢分享,学到很多东西哦
谢谢光顾!
感谢光顾~
博主你好 我想问一下 view视图中的 header和footer 可以不应用吗
可以,不调用:$this->render();,就不会调用渲染,这样的话需要自己手动
echo()
或者exit()
好的 谢谢 echo() exit() 是什么呢 定义好的方法?
PHP的内置函数
比方说我现在需要从login方法跳转到login页面 不用render 怎么去写
这个用header()函数来实现。
你好 歪麦 我怎么可以得到我URL传递的参数呢 $_GET['name']?
歪麦您好,我刚刚开始学习这个mvc框架,在自动加载类上有一些问题。请问loadClass($className) 这个函数中,参数是如何传入进去的?同时自动加载类是怎么确定类名的变化,又是如何寻找子类的父类并且引入的?反复看了多遍loadClass($className)函数还是没有看明白,也没有看到调用loadClass时传入的参数
这个是PHP实现的,为什么叫“自动”加载,就是参数会自动传递到方法里面。
比如我们调用一个方法:
Math::add($a, $b);
用了自动加载的话,PHP会自动把类名传给
loadClass
,这里就是Math
。那php的这个自动加载机制,我想了解它的实现远离,就是spl_autoload_register这个方法实现的吗?谢谢博主!
根据楼主的代码我这里总是报 控制器不存在
克隆一份github的代码
/**
* 用户Model
*/
ItemModel -> search($keyword)
这个出现页面空白
// 将数组转换成插入格式的sql语句
private function formatInsert($data)
{
$fields = array();
$names = array();
foreach ($data as $key => $value) {
$fields[] = sprintf("%s", $key);
$names[] = sprintf("'%s'", $key);
//这里是不是错了,$names[] = sprintf("'%s'", $value);
}
$field = implode(',', $fields);
$name = implode(',', $names);
return sprintf("(%s) values (%s)", $field, $name);
}
博主你好,对于路由分发,我有些问题想要请教
在我的项目中我没有引入头尾文件,而是采用在iframe中跳转,所以出现了一个情况:
相同的代码,如href(‘class/index’)
在iframe外(入口页)跳转为...../class/index;是正常的。
但在iframe中(如class控制器下的页面中)跳转为....../class/class/index;
怎么忽然间多了一个class,让我不明觉厉
这么神奇
是啊,我很焦灼
在跳转时使用 /index/index 形式。。就好了
可以再index.php里加载一个加密解密函数,用来加密传递参数,就更好了
本人不会php,但是感觉博主描述的很清晰,看着很舒服,一点都不繁琐,关键点又没拉下,博主牛逼!谢谢;-)
感谢支持:)
楼主你好,你的框架很好,给你个赞。我不知道你用过谷歌浏览器打开过没,我用时,打开出现您要访问的网站包含有害程序
test1.com 上的攻击者可能会试图骗您安装有损浏览体验的程序(例如更改您的主页或在您访问的网站上显示额外的广告)。不能访问。其它360和ie正常.我是新手,这个问题是什么原因,怎么解决
歪麦您好,model 层怎么用多个数据库表,是不是每个表要建个model,我怎么又建个model,把model中$items变成$dns,在$items控制中,加了一行,$this->assign('dhs', $dhs);到views表中和您的一样,建个
<a href= >
怎么显示Undefined variable: dns in F:\web\kuangj\app\views\item\index.php on line 6
还有就是model是不是每个都要如ItemModml或IdhModml。后面的modml,不能去掉吗
歪麦您好,最近没来吗?model怎么设置查询多个数据库
楼主你好,我想请教一下
按您说的配置完成后,首页可以正常显示,但是点击页面中热河一个按钮,都会提示
Not Found
The requested URL /item/manage/2 was not found on this server.
请问是哪里出了问题呢?
还有一点,之前配置的时候出现控制器不存在的情况,我将
// 获取控制器名
//$controllerName = ucfirst($urlArray[0]);
// 获取动作名
//array_shift($urlArray);
//$actionName = $urlArray ? $urlArray[0] : $actionName;
这些代码注释掉就可以正常通过,是不是这里出了问题导致了所有的跳转都报错呢?
楼主你好,如果头部和尾部模版,用是公用的,如果里边要调用数据库,怎么给那一个公用的调用数据,不用都要在每个控制器都做一遍
暂时没做这么复杂呢,你可以实现下:)
框架怎么弄个php生成的验证码并验证
可以使用composer,拉别人现成的项目来实现
博主,我下载的代码之后就出现这样额错误app\controllers\Shixun-1Controller鎺у埗鍣ㄤ笉瀛樺湪 这是什么错误呢,帮忙解一下
是不是文件的编码不是utf-8?或者html模板不是或没指定编码格式?
在 index.php 首行加上 header("Content-type:text/html;charset=utf-8");
博主你好,为什么我访问的时候会出现app\controllers\ProjectController控制器不存在啊?
你好 博主请问 直接运行 index.php就可以运行整个项目吗
index.php是入口文件,所有的请求都会经过index.php的~
帮助很大
感谢支持。
謝謝博主分享
學習了
不是说controller thin,而model fat吗?这方面应该还可以改进
是的,现在的程序只是演示,实际使用时controller应尽量“瘦”
有木有人实现的哇。。。不管怎么改都是控制器不存在,求帮助啊。
看评论 也木有正确解释
去github下载下来 还是提示这个。。。求解呀
app\controllers\ItemController控制器不存在
如果是本地的话,可能你需要把你项目名去掉
//本地
$pattern = '/fastphp-master/';
if (preg_match($pattern, $url))
{
$url = preg_replace($pattern, '', $url);
define('PROJECT_NAME', trim($pattern, '/'));
}else
{
define('PROJECT_NAME','');
}
是添加在route里面 $url = $_SERVER['REQUEST_URI'] 这个的后面吗?没有用哇- - 还是提示一模一样的
Nginx配置是否正确?
成功运行,给楼主个赞
不是说好了手把手教学吗? 你人在哪呢?
你住哪?我这就过去 /斜眼笑
我在海淀区上地七街等你QuQ
好,马上来,嘿嘿
我是个菜鸟QuQ,defined('CORE_PATH') or define('CORE_PATH', __DIR__);这个什么意思没太懂
这里有两个点,一个是defined函数(注意,不是define),另一个是or的熔断机制,把两个串起来就容易理解了。
为什么要这样写啊
在fastphp/Fastphp.php中有一行代码会带来错误:
// 获取控制器名
$controllerName = ucfirst($urlArray[0]);
如果地址没有输入控制器名如http://localhost/index.php,则会报错,
"app\controllers\Index.phpController控制器不存在"
可以这样
if (count($urlArray) == 2){
// 获取控制器名
$controllerName = ucfirst($urlArray[0]);
}
大神,我的php可能有点问题,要不然也不会出现这样问题,就是打开目录,出现index.php不会自动执行该文件,这是为什么?
配置Apache或者nginx,设置index(首页)为index.php
对的,还没配置首页
dalao问个问题 我按照dalao您的做法写了一个MVC框架 可是部署完后发现报错:
PHP Fatal error: Uncaught Error: Class 'application\controllers\NoExistController' not found in 路径:73
Stack trace: #0 路径: HksMVC\HksMVC->Route() #1 D:\web site\MVCdemo\index.php(16): HksMVC\HksMVC->Run() #2 {main} thrown in D:\web site\MVCdemo\HksMVC\HksMvc.php on line 73
自己写的控制器吗?得按照规范来写哟,要是自己实现的话,可以调试到路由方法里面看看具体的调用过程。
app\controllers\FastphpController控制器不存在
emm 他老是提示找不到class 然后我干脆把那个exit给注释掉了 然后emmm 我感觉要include控制器才行呐
内核类是自动加载的,不需要手动include的
嘿嘿.. 我自己改装了一下 我就狂include了 然后我在实例化控制器的时候也会提前引入控制器
我也成功了,提示控制器不存在的,关键还是,要建个虚拟主机,比如我在localhost下建个project文件夹,然后将东西都导入进来,按照要求进行修改后(就是数据库设置这些基本的)。新建一个虚拟主机,根文件就设在project下。这样你访问的时候,直接访问比如:project.com(就是localhost/project/)这样你访问,就不会提示控制器不存在了。。。反正我是放弃了两个礼拜 重写试后可以的。还是真心感谢作者, 很有用
我花了4days 深思熟虑去思考这个问题 然后自己深度重写了(这个框架 然后就ok了
大佬,除了增删改查之外,考虑出登录注册的教程吗?我是个前端,最近向学习后端,非常期待和饥渴啊
注册: 连接数据库->判断用户名是否重复->其他条件->数据库插入
登录: 连接数据库->查询->验证
主要是想学习登录相关的session这块 要怎么使用 要怎么封装
session_start();
$_session['xxx'];
话说为什么我有头像了233
想请教一下,在使用这个框架时发现一个问题,Sql.php 中的 formatParam 绑定多个字段时,$sth->fetch执行返回false,而我把其中的$params中的数值echo出来,发现没问题,最后执行fetch 却是返回false
很不错,初学者复制代码都能正常运行!
app\controllers\Fastphp-masterController控制器不存在
你的这个是php7的版本,保这个错
换成php5版本就行了
php7.0.12-nts提示这个,换成php5的版本就行
Warning: include_once(/fastphp/base/Controller.php): failed to open stream: No such file or directory in F:\phpStudy\WWW\ZongHeFuXi\lianxi\MVC\fastphp\Fastphp.php on line 60
Warning: include_once(): Failed opening '/fastphp/base/Controller.php' for inclusion (include_path='.;C:\php\pear') in F:\phpStudy\WWW\ZongHeFuXi\lianxi\MVC\fastphp\Fastphp.php on line 60
Fatal error: Class 'fastphp\base\Controller' not found in F:\phpStudy\WWW\ZongHeFuXi\lianxi\MVC\app\controllers\IndexController.php on line 6
博主,为什么报我的控制器不存在???但是我的controllers下面是存在的
出现乱码的,在根目录index.php顶部添加这句
header("Content-Type: text/html;charset=utf-8");
楼主您好,初学mvc,非常感谢您的教程,请教下2个问题:
1、我git下载的配置好可以运行,但是速度感觉比较卡,编辑、删除、返回都要2秒左右。
2、我现有站点是一个总的目录www,里面有几个非mvc的小系统aaa、bbb、ccc,访问各个系统是通过域名+各目录来区分,如localhost/aaa、localhost/bbb这样。现在如果我要加这个mvc的例子,就得配置站点目录到例子的目录,这样我aaa、bbb等系统就无法访问了,请问怎么解决呢?谢谢。
问题2已通过vhosts解决,问题1卡的情况不明白,现在是卡1秒左右,继续学习吧,以后看能不能理解
app\controllers\Fastphp-masterController鎺у埗鍣ㄤ笉瀛樺湪
我借鉴这个框架和其他框架的优点写了一个自己框架,然后用框架写了一个文章程序,谢谢楼主分享自己的经验,有兴趣的可以去看看我的文章程序http://misw.top
好棒,现在所有人都可以改你的文章,是不是再加些权限管理
楼主你看到的是可以访问修改文章的页面,但是其实没有权限的话修改文章的话会提示权限不足的,不过听取了你的意见后,现在我加了不能访问那个修改文章的页面了,谢谢楼主指点。
支持!
源码打包内个连接不好使了 我想要一个源码
为什么在调用检测 类是否存在是 如果存在 我会自动输出 类的路径呢 和你的检测方法一样 你的源码 就没有输出
Not Found
The requested URL /item/add was not found on this server.
----------
打开httpd.conf
(1)
Options FollowSymLinks
AllowOverride None
改为
Options FollowSymLinks
AllowOverride All
(2)去掉下面的注释
LoadModule rewrite_module modules/mod_rewrite.so
打开extra下和httpd-vhosts.conf
Options FollowSymLinks
AllowOverride None
改为
Options FollowSymLinks
AllowOverride All
能不能像ThinkPHP一样搞一个自动生成模块的,蛮好用的。
1个build.php
1个composer.lock
1个composer.json
1个fast
仅学习用而已啦
好blog, 我现在才发现
你里面的phpunit.xml文件的作用
你使用composer时的vender文件夹呢
iis环境下运行不了,有什么特殊操作吗
iis下访问路由是404,路由用不了是什么原因,有人解答一下吗,感谢!
http://acphp.io/item/index/
----------------------------------
Not Found
The requested URL /item/index/ was not found on this server.
---------------------------------------------------------------------
明明有为什么会找不到呢。。。
没有解析。本地目录上没有这个文件,建议用apache或nginx。
运行的时候报错了
请问这个怎么解决呢
大牛,我想打赏你,这里没有打赏入口啊 ....写的太好了!
导航栏“关于&打赏”加了二维码:)
楼主的sql.php文件里面应该是各种类的操作,里面有查询单条,多条,以及增改删的操作,楼主可以再加几个常用的吗?比如'join', 'union', 'group', 'having', 'limit', 'order', 'force', 'comment',这些常用的,可以吗?
可以加的,不过目前暂时在忙别的事情,你也可以加呀,然后pull requests
题主SQLSTATE[HY000] [1049] Unknown database 'project' 出现这个问题怎么解决啊,数据库里已经有project了啊
手动连一下数据库是否可以连上?
楼主 App.php 里这行代码什么意思呢
$dispatch = new $controller($controllerName, $actionName);
我如果换成 $dispatch = new $controller(); 也是可以的呀
能请教一下laravel等框架对路由功能是怎么实现的吗
看laravel的源码就晓得了
博主右侧的目录是后台生成的还是怎么做的?如果是后台生成的是使用的什么功能呢?
主题支持的。
歪麦 你好,从数据库里面读出来的数据如何复用,看你的代码,每个方法里面都要重新 new 一个模型实例对象,如何复用这个模型实例对象。
new给一个变量,再用就能复用了。
大神你好,我尝试新添加一个public,并修改APP_PATH,域名指向public,修改INDEX.PHP,define('APP_PATH', __DIR__ . '/../');
首页访问正常,但是子页访问500错误,是路由错误,这个如果修改?想更加理解一下,希望不吝赐教.
楼主我想问下这个框架下保存session该如何做呢
class Base extends Controller{
public function _initialize(){
//判断用户是否登录
if($_SESSION['user']['user']==null){
header( 'location: /user/login');
exit();
}
}
}
我加了个基类控制器其它控制器继承时为什么这个不会执行(不登录时不会调转到登录页面)怎么改,谢谢
<?php
namespace app\controllers;
use fastphp\base\Controller;
use app\models\Admin;
use fastphp\SESSION;
class Base extends Controller{
public function __construct() {
parent::__construct();
//public function _initialize(){
$sid = $_SESSION['auth'];//检测session是否存在,不存在就跳登录页面
if (! isset($sid)) {
header("Location: Account/login");//登录地址
}
}
}用构造函数会出现错误,不显示模版
Warning: Missing argument 1 for fastphp\base\Controller::__construct(), called in E:\web\mykjweb\app\controllers\Base.php on line 12 and defined in E:\web\mykjweb\fastphp\base\Controller.php on line 14
Warning: Missing argument 2 for fastphp\base\Controller::__construct(), called in E:\web\mykjweb\app\controllers\Base.php on line 12 and defined in E:\web\mykjweb\fastphp\base\Controller.php on line 14
window糸统入口怎么写
你好,请问where多个参数查询是怎么使用?
老哥, fastphp/Fastphp.php #152 public function loadClass($className)
这个方法的 $className参数 是不是有点多余,在其他地方都没有传参
还是说在其他地方有作用
这是自动载入必要的参数,你打印出来就知道了,会打印出当前调用的类的完整类名(包含命名空间)
纠正错误: 会导致$_GET解析不到参数
nginx重写配置
try_files $uri $uri/ /index.php$args;
应改为
try_files $uri $uri/ /index.php?$args;
这东西我十年前玩过 十年后还是老样子
有一个问题 前端上传一个文件到后台 $_FILES里是空的
我仔细看了看
$url = $position === false? $url : substr($url,0,$position);
这句似乎不过是锦上添花,没有丝毫用处.
$url没有任何变化
似乎是我搞错了,注释没看,不要看到我,不要看到我......
为什么你的博客做的这么简单
把config.php里默认的controller改成Index, Item的搜索不可用了(domain/item/?keyword=keyword), 必须手动加上index.php在前面才行(domain/index.php/item/?keyword=keyword), 请问这是什么问题?
基于大佬您的框架完善了一下,虽说还有很多bug
https://git.eosrce.com/exac0xp/the-end