手把手编写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>
如果是Nginx服务器,修改配置文件,在server
块中加入如下的重定向:
<span class="hljs-title">location</span> / {
<span class="hljs-comment"> # 重新向所有非真是存在的请求到index.php
</span><span class="hljs-title"> try_files</span> <span class="hljs-variable">$uri</span> <span class="hljs-variable">$uri</span>/ /index.php<span class="hljs-variable">$args</span>;
}
这样做的主要原因是:
(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();
注意,上面的PHP代码中,并没有添加PHP结束符号?>
。
这么做的主要原因是:
对于只有 PHP 代码的文件,最好没有结束标志?>
,
PHP自身并不需要结束符号,不加结束符让程序更加安全,很大程度防止了末尾被注入额外的内容。
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 框架核心类
入口文件对框架类做了两步操作:实例化,调用run()方法。
实例化操作接受$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架构的职责划分原则》。
参考资料:
运营报错了。
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
您好,两表联查该怎么封装比较好呢?