`
congfeng02
  • 浏览: 195872 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

PHP框架设计入门之二:管理用户

阅读更多

PHP框架设计入门之二:管理用户 ----------------------------------------

In part 1, we covered the basic class structure of the framework andlaid out the scope of the project. This part adds session handling toour application and illustrates ways of managing users.

这是PHP应用程序框架设计系列教程的第二部分。在第一部分,我们已经介绍框架的基础类结构,并展示了项目的大体。这一部分,我们将在程序中添加会话处理功能,并演示管理用户的各种方法。

Sessions

会话

引用:

HTTP is a stateless protocol and, as such, does not maintain anyinformation about the connections made to the server. This meansthat, with HTTP alone, the web server cannot know anything about theusers connected to your web application and will treats each pagerequest as a new connection. Apache/PHP gets around this limitation byoffering support for sessions. Conceptually sessions are a fairlysimple idea. The first time a web user connects to the server, he isassigned a unique ID. The web server maintains session information ina file, which can be located using this ID. The user also has tomaintain this ID with each connection to the server. This is typicallydone by storing the ID in a cookie, which is sent back to the server aspart of the typical Request-Response1sequence. If the user does not allow cookies, the session ID can alsobe sent to the server with each page request using the query string(the part of the URL after the “?”). Because the web client isdisconnected, the web server will expire sessions after predefinedperiods of inactivity.

HTTP是一种无状态的协议,正因为如此,它没有包含任何与服务器连接的相关信息。这就意味着,HTTP是孤立的,web服务器并不知道用户与你web程序相连接的任何信息,并且服务器会将每个页面请求视为一个新的连接。Apache/PHP通过提供对会话的支持来避开这一限制。从概念上来说,会话是相当简单的。在一个用户第一次连接到服务器的时候,他被分配一个唯一的ID。web服务器在一个文件中维护会话信息(译注:即把会话信息存储到文件中),于是可以通过这个ID来定位用户信息。用户同样会在每次连接中维护这个ID。最典型的作法,就是将ID存储在cookie中,之后,这个ID会作为请求-应答序列的一部分发回给服务器。如果用户不允许使用cookie,会话ID同样可以在请求每个页面时,通过query字符串(即URL中?以后的部分)发回给服务器。因为web客户端会断开连接,所以web服务器会在一定周期后,使那些不活动的会话信息过期。

引用:

We will not go over configuring Apache/PHP in this article butwill utilize sessions to maintain user information in our application.It is assumed that session support is already enabled and configured onyour server. We will pick up where we left off in part 1 of this serieswhen we described the system base class. You may recall that the firstline in class_system.phpis session_start(), which starts a new user session if none exists ordoes nothing otherwise. Depending on how your server is configured,this will cause the session ID to be saved in the client’s cookie fileor passed as part of the URL. The session ID is always available to youby calling the build in function session_id(). With these tools athand, we can now build a web application that can authenticate a userand maintain the user’s information as he is browsing the differentpages on the site. Without sessions, we would have to prompt the userfor their login credentials every single time they request page.

我们不想在这篇文章中过多地谈论Apache/PHP的配置,除了利用会话来维护用户信息。我们假设会话支持功能已经开启,并在你的服务器上配置好了。我们将直接从本序列教程第一部分谈论系统基础类时,被我们搁在一边的地方谈起。你可能还记得class_system.php的第一行是session_start(),这一句的作用是,如果不存在会话信息,则开始一个新的用户会话,否则不做其他的事情。根据你服务器的配置,开始会话的时候,会话ID会被保存在客户端的cookie里或者作为URL的一部分进行传递。当你调用内建的session_id()函数时,总可以得到会话ID。通过这些工具,我们现在可以建立一个web应用程序,它可以对用户进行验证,并且能够在用户浏览网站不同页面的时候去维护用户的信息。如果没有会话,那么用户每一次请求页面的时候,我们就不得不提醒用户进行登录。

引用:

So what will we want to store in the session? Let’s start withthe obvious like the user’s name. If you take a look at class_user.phpyou will see the rest of the data being stored. When this file isincluded, the first thing that is checked is whether a user is loggedin (default session values are set if the users id is not set). Notethat the session_start() must have already been called before we startplaying with the $_SESSION array which contains all our session data.The UserID will be used to identify the user in our database (whichshould already be accessible after part one of this series). The Rolewill be used to determine whether the user has sufficient privileges toaccess certain features of the application. The LoggedIn flag will beused to determine if the user has already been authenticated and thePersistent flag will be used to determine whether the user wants toautomatically be logged in based on their cookie content.

那么,我们应该在会话中存储什么信息呢?我们一下子就可以想到如用户名这类信息。如果你看一下class_user.php,你会看到其他要存储的数据。(在程序中)include这个文件的时候,首先会检查用户是否登录(如果没有用户id,那么会设置一个默认的会话值)。注意,session_start()必须在我们使用$_SESSION数组之前调用,$_SESSION数组包含所有我们的会话数据。UserID用来标识存储在我们数据库中的用户(如果您已经完成了本系列教程的第一部分,那么这个数据库中的数据应该可以访问了)。Role(角色)是用来检测用户是否有足够的权限去访问程序中的某一部分功能。LoggedIn标识用来检测用户是否通过验证,Persistent标识用来检测用户是否想依靠他们的cookie内容自动进行登录。

复制PHP内容到剪贴板

PHP代码:

//session has not been established

if (!isset($_SESSION['UserID']) ) {

set_session_defaults();

}

//reset session values

function set_session_defaults() {

$_SESSION['UserID'] = '0'; //User ID in Database

$_SESSION['Login'] = ''; //Login Name

$_SESSION['UserName'] = ''; //User Name

$_SESSION['Role'] = '0'; //Role

$_SESSION['LoggedIn'] = false; //is user logged in

$_SESSION['Persistent'] = false; //is persistent cookie set

}

User Data

用户数据

We store all the user data in our database in table tblUsers. Thistable can be created using the following SQL statement (mySQL only).

我们将所有的用户数据存储到数据库的tblUsers表,这个表可以使用下面的SQL语句来创建(仅限MySQL)

复制PHP内容到剪贴板

PHP代码:

CREATE TABLE `tblUsers` (

`UserID` int(10) unsigned NOT NULL auto_increment,

`Login` varchar(50) NOT NULL default '',

`Password` varchar(32) NOT NULL default '',

`Role` int(10) unsigned NOT NULL default '1',

`Email` varchar(100) NOT NULL default '',

`RegisterDate` date default '0000-00-00',

`LastLogon` date default '0000-00-00',

`SessionID` varchar(32) default '',

`SessionIP` varchar(15) default '',

`FirstName` varchar(50) default NULL,

`LastName` varchar(50) default NULL,

PRIMARY KEY (`UserID`),

UNIQUE KEY `Email` (`Email`),

UNIQUE KEY `Login` (`Login`)

) TYPE=MyISAM COMMENT='Registered Users';

引用:

This statement creates a bare-bones user table. Most of the fields are selfexplanatory. We need the UserID field to uniquely identify each user.The Login field, which must also be unique, stores the user's desiredlogin name. The Password field stores the MD5 hash of the user'spassword. We are not storing the actual password for security andprivacy reasons. Instead we can compare the MD5 hash of the passwordentered with the value stored in this table to authenticate the user.The user's Role will be used to assign the user to a permission group.Finaly, we will use the LastLogon, SessionID, and SessionIP fields totrack the user's usage of our system including the last time the userlogged in, the last PHP session ID the user had, and the IP address ofthe user's host. These fields are updated each time the usersuccessfully logs in using the _updateRecord() function in the usersystem class. These fields are also used for security in preventingcross-site scripting attacks.

这个语句建立了一个大概的用户表。大多数字段不言自明。我们用UserID这个字段来唯一标识每个用户。Login字段同样也必须是唯一的,存储用户使用的登录名。Password字段用来存储用户密码的MD5散列值。我们没有存储实际的密码是因为安全和隐私的原因。我们可以拿用户输入的密码的MD5散列值与数据表中的进行对比来验证用户。用户角色用来将用户分配到一个许可组。最后,我们用LastLogon, SessionID和SessionIP字段来跟踪用户对系统的使用情况,包括用户最后登录时间,用户最后使用的会话ID,用户机器的IP地址。用户每次成功登录后,会调用user系统类中的_updateRecord()函数来更新这些字段值。这些字段同时也可以用来保证安全性,保证不受XSS(跨站脚本)攻击。

复制PHP内容到剪贴板

PHP代码:

//Update session data on the server

function _updateRecord () {

$session = $this->db->quote(session_id());

$ip = $this->db->quote($_SERVER['REMOTE_ADDR']);

$sql = "UPDATE tblUsers SET

LastLogon = CURRENT_DATE,

SessionID = $session,

SessionIP = $ip

WHERE UserID = $this->id";

$this->db->query($sql);

}

Security Issues

Authentication

验证

Now that we understand the various security issues involved, lets lookat the code for authenticating a user. The login() function accepts alogin name and password and returns a Boolean reply to indicatesuccess. As stated above, we must assume that the values passed intothe function came from an untrusted source and use the quote() functionto avoid problems. The complete code is provided below.

现在我们已经了解了各种相关的安全问题,下面我们来看一看验证用户的代码。login()函数接收一个登录名和密码,返回一个Boolean(布尔值)来标明是否正确。正如上面所说的,我们必须假定传入函数中的值是来自于不可靠的来源,用quote()函数来避免问题。完整的代码如下:

复制PHP内容到剪贴板

PHP代码:

//Login a user with name and pw.

//Returns Boolean

function login($username, $password) {

$md5pw = md5($password);

$username = $this->db->quote($username);

$password = $this->db->quote($password);

$sql = "SELECT * FROM tblUsers WHERE

Login = $username AND

Password = md5($password)";

$result = $this->db->getRow($sql);

//check if pw is correct again (prevent sql injection)

if ($result and $result['Password'] == $md5pw) {

$this->_setSession($result);

$this->_updateRecord(); //update session info in db

return true;

} else {

set_session_defaults();

return false;

}

}

To logout, we have to clear the session variables on the server as well asthe session cookies on the client. We also have to close the session.The code below does just that.

用户注销的时候,我们要清理在服务器上的会话变量,还有在客户端的会话cookie。我们还要关闭会话。代码如下:

复制PHP内容到剪贴板

PHP代码:

//Logout the current user (reset session)

function logout() {

$_SESSION = array(); //clear session

unset($_COOKIE[session_name()]); //clear cookie

session_destroy(); //kill the session

}

Inevery page that requires authentication, we can simply check thesession to see if they user is logged in or we can check the user'srole to see if the user has sufficient privileges. The role is definedas a number with the larger numbers indicating more rights. The codebelow checks to see if the users has enough rights using the role.

在每一个页面都要求验证,我们可以简单地检查一下会话,看用户是否已经登录,或者我们可以检查用户角色,看用户是否有足够的权利。角色被定义为一个数字(译者注:即用数字来表明角色),更大的数字意味着更多的权利,下面的代码使用角色来检查用户是否有足够的权利。

复制PHP内容到剪贴板

PHP代码:

//check if user has enough permissions

//$role is the minimum level required for entry

//Returns Boolean

function checkPerm($role) {

if ($_SESSION['LoggedIn']) {

if ($_SESSION['Role']>=$role) {

return true;

} else {

return false;

}

} else {

return false;

}

}

Login/Logout Interface

登录/注销的接口

引用:

Now that we have a framework for handling sessions and user accounts,we need an interface to allow the user to login and out. Using ourframework, creating this interface should be fairly easy. Let us startwith the simpler logout.php page which will be used to log a user out.This page has no content to display to the user and simply redirectsthe user to the index page after having logged him out.

现在我们已经有一个处理会话和用户账号的框架了,我们需要一个接口,这个接口允许用户登录和注销。使用我们的框架,建立这样的一个接口应该是十分简单的。下面我们就从比较简单的logout.php页面开始,这个页面用来注销用户。这个页面没有任何内容展现给用户,只是在注销用户以后,简单将用户重定向到index页面。

复制PHP内容到剪贴板

PHP代码:

define('NO_DB', 1);

define('NO_PRINT', 1);

include "include/class_system.php";

class Page extends SystemBase {

function init() {

$this->user->logout();

$this->redirect("index.php");

}

}

$p = new Page();

引用:

First we define the NO_DB and NO_PRINT constants to optimize the loading time of this page (asdescribed in Part 1 of this series). Now all we have to do is use theuser class to log the user out and redirect to another page in thepage's initialization event.

首先,我们定义NO_DB和NO_PRINT常量来优化加载这个页面的时间(正如我们在本系列教程中第一部分描述的那样)。现在,我们要做的所有事情,就是使用user类来注销用户,并在页面初始化事件中重定向到另外的页面。

引用:

The login.php page will need an interface and we will use the system'sform handling abilities to simplify the implementation process. Details of how this works will be described in Parts 3 and 4 of thisseries. For now, all we need to know is that we need an HTML form thatis linked the application logic. The form is provided below.

这个login.php页面需要一个接口,我们使用系统的表单处理能力简化处理的实现过程。至于这个过程是如何运作的,我们将会在本系列教程的第三和第四部分详细介绍。现在呢,我们所需要知道的全部事情,就是我们需要一个HTML表单,这个表单与应用程序的逻辑相连接。表单代码如下:

复制PHP内容到剪贴板

PHP代码:

<form action="<?=$_SERVER['PHP_SELF']?>" method="POST" name="<?=$formname?>">

<input type="hidden" name="__FORMSTATE" value="<?=$_POST['__FORMSTATE']?>">

<table>

<tr>

<td>Username:

<td><input type="text" name="txtUser" value="<?=$_POST['txtUser']?>"></td>

</tr>

<tr>

<td>Password:

<td><input type="password" name="txtPW" value="<?=$_POST['txtPW']?>"></td>

</tr>

<tr>

<td colspan="2">

<input type="checkbox" name="chkPersistant" <?=$persistant?>>

Remember me on this computer

</td>

</tr>

<tr style="text-align: center; color: red; font-weight: bold">

<td colspan="2">

<?=$error?>

</td>

</tr>

<tr>

<td colspan="2">

<input type="submit" name="Login" value="Login">

<input type="reset" name="Reset" value="Clear">

</td>

</tr>

</table>

</form>

引用:

Now we need the code to log a user in. This code sample demonstrates how touse the system framework to load the above form into a page template,handle the form events, and use the user class to authenticate the user.

现在我们来编写用户登录的代码。这个代码演示了如何使用系统框架将上面的表单加载到一个页面模板中,以及处理表单事件、使用user类来验证用户。

复制PHP内容到剪贴板

PHP代码:

class Page extends SystemBase {

function init() {

$this->form = new FormTemplate("login.frm.php", "frmLogin");

$this->page->set("title","Login page");

if (!isset($_POST['txtUser']) && $name=getCookie("persistantName")) {

$this->form->set("persistant","checked");

$_POST['txtUser']=$name;

}

}

function handleFormEvents() {

if (isset($_POST["Login"])) {

if($this->user->login($_POST['txtUser'],$_POST['txtPW'])) {

if (isset($_POST['chkPersistant'])) {

sendCookie("persistantName", $_POST['txtUser']);

} else {

deleteCookie("persistantName");

}

$this->redirect($_SESSION['LastPage']);

} else

$this->form->set("error","Invalid Account");

}

}

}

$p = new Page();

引用:

Onpage initialization, the form is loaded into the page template, thepage's title is set and the user's login name is pre-entered into theinput field if the persistent cookie is set. The real work happens whenwe handle the form events (i.e. when the user presses a button tosubmit the page). First we check if the login button was clicked. Thenwe use the login name and password submitted to authenticate the user.If authentication is successful, we also set a cookie to remember theusers name for the next time. If the authentication fails, an error isdisplayed on the page.

在页面初始化时,表单被加载到页面模板中,页面的标题已经被设置好,如果有永久的cookie,那么用户的登录名还会被预先输入到输入框中。当我们处理表单的时候,我们就真正有事情要做了(比如:当用户按下一个按钮提交页面)。首先,我们检查登录按钮是否被点击了。然后,我们使用提交过来的登录名和密码来验证用户。如果验证成功,我们同时设置一个cookie来记住用户名以便下次使用。如果验证失败,则会在页面上显示一个错误。

Summary

总结

引用:

So far, we have laid the foundation for how our application will behaveand how the framework will be used. We added user managementcapabilities to our application and covered several security issues.Read the next part to see how to implement page templates and separateapplication logic from the presentation layer.

目前为止,我们已经谈论了我们的应用程序如何运转及框架如何使用的基本信息。我们为我们的应用程序添加了用户管理能力,并且谈论了几个安全问题。下一部分,将可以看到如何实现页面模板,从而将应用程序逻辑从表现层中分离出来。

安全问题

This seems like a logical place to address several security issues thatcome up when developing web applications. Since security is a majoraspect of user management, we need to be very careful not to leave anycareless bugs in this part of our code.

这一部分看起来应该来考虑几个在开发web应用程序会遇到的安全问题。因为安全性是用户管理的一个主要方面,我们得非常细心,不在我们这一部分的代码中留下任何因为粗心导致的bug。

引用:

The first issue that needs to be addressed is the potential for SQLinjection in any web application that uses posted web data to query adatabase. In our case, we use the login name and password supplied bythe user to query the database and authenticate the user. A malicioususer can submit SQL code as part of input field text and maypotentially achieve any of the following: 1) login without having avalid account, 2) determine the internal structure of our database or3) modify our database. The simplest example of this is the SQL codeused to test if the user is valid.

第一个要考虑的问题是,不管在任何web应用程序中都会遇到的——SQL注入攻击(SQL注入会发送web数据来进行数据库查询)。在我们的情况中,我们使用用户提供的登录名和密码来查询数据库进而验证用户。一个怀有恶意的用户可以提交SQL代码作为输入文本的一部分,从而可能达到下面的几个目的:1 不需要拥有有效的账号即可登录 2 探测我们数据库的内部结构 3 修改我们的数据库。下面是一个非常简单的例子,用来测试用户是否有效。

复制PHP内容到剪贴板

PHP代码:

$sql = "SELECT * FROM tblUsers

WHERE Login = '$username' AND Password = md5('$password')";

引用:

Suppose the user enters admin'-- and leaves the password blank. The SQL codeexecuted by the server is: SELECT * FROM tblUsers WHERE Login ='admin'--' AND Password = md5(''). Do you see the problem? Instead ofchecking the login name and password, the code only the checks thelogin name and the rest is commented out. As long as there is a useradmin in the table, the query will return a positive response. You canread about other SQL injection exploits in David Litchfield's publication.

设想一下,用户输入 admin'-- ,然后将密码框留空。服务器执行的SQL代码则为:SELECT * FROM tblUsers WHERE Login = 'admin'--' AND Password = md5('')。你是否发现问题了?代码不同时检查登录名和密码了,只是检查登录名,(因为)余下的部分被注释掉了。只要在表里面有一个admin用户,这个查询就会返回一个肯定的回答。你可以通过阅读David Litchfield的文章(http://blackhat.com/presentation ... u-05-litchfield.pdf)来了解其他的SQL注入攻击。

引用:

How do you protect yourself from this kind of threat. The firststep is to validate any data sent to the SQL server that comes from anuntrusted source (i.e. the user). PEAR DB provides us with thisprotection using the quote() function which should be used on anystring sent to the SQL server. Our login() function shows otherprecautions that we can take. In the code, we actually check thepassword in both the SQL server and in PHP based on the recordreturned. This way, the exploit would have to work for both the SQLserver and PHP for an unauthorized user to get in. Overkill you say?Well, maybe.

你该怎么样保护你自己的代码免受这种类型的威胁呢。第一步是检验任何从不可靠的来源(比如:用户)发送到SQL服务器的数据。PEAR DB中的quote()函数为我们提供了这样的保护,这个函数可用于发送到SQL服务器的任何字符串。我们的login()函数(译注:该函数请见下文)显示了我们可以采取的其他预防措施。在我们的代码中,我们在SQL服务器和PHP中(根据SQL服务器返回的记录)都检查了密码。这样的话,攻击必须同时对SQL服务器和PHP都有效,才能使一个未验证的用户登录进去。你想说这杀伤力太大了吧?是的,也许吧。

引用:

Another issue that we have to be aware of is the potential for sessionstealing and cross site scripting (XSS). I won't get into the variousways that a hacker can assume the session of another authenticated userbut rest assured that it is possible. In fact, many methods are basedon social engineering rather than bugs in the actual code so this canbe a fairly difficult problem to solve. In order to protect our usersfrom this threat, we store the Session IP and Session ID of the usereach time he logs in. Then, when any page is loaded, the users currentSession ID and IP address are compared to the values in the database.If the values don't match then the session is destroyed. This way, if ahacker gets a victim to log in from one machine and then tries to usethat active session from his own machine, the session will be closedbefore any harm can be done. The code to implement this is bellow.

另一个问题是,我们必须警惕会话窃取和跨站脚本攻击(XSS)的可能性。我不想过多地谈论一个黑客冒充其他已验证用户会话信息的各种方法,但确定的是那确实有可能。事实上,比起利用代码中的bug,许多基于社会工程学的方法更可以称得上是十分难解决的问题。为了保护我们的用户不受这样的威胁,我们在用户每次登录的时候存储他的会话IP和会话ID。然后,当页面加载完成,我们就拿用户当前的会话ID和IP地址和数据库中的值进行比对。如果不匹配,那么就破坏会话信息。这样子,如果一个黑客让一个受害者从一台机器上登录,然后试着从他自己的机器使用受害者的活动会话,那么在他做出任何破坏之前会话就会被关闭。具体的实现代码如下:

复制PHP内容到剪贴板

PHP代码:

//check if the current session is valid (otherwise logout)

function _checkSession() {

$login = $this->db->quote($_SESSION['Login']);

$role = $this->db->quote($_SESSION['Role']);

$session = $this->db->quote(session_id());

$ip = $this->db->quote($_SERVER['REMOTE_ADDR']);

$sql = "SELECT * FROM tblUsers WHERE

Login = $login AND

Role = $role AND

SessionID = $session AND

SessionIP = $ip";

$result = $this->db->getRow($sql);

if ($result) {

$this->_setSession($result);

} else {

$this->logout();

}

}

分享到:
评论

相关推荐

    84PHP开源框架 v1.1.0

    4PHP是一套完全遵守APACHE开源协议的便捷PHP框架,独特的模块化设计,使得框架简洁易懂。一行代码即可完成在线支付、发送短信、分页等功能,前所未有的简单和高效!同时,84PHP还具有云服务功能,这也是国内首款与...

    PHP 程序设计简明教程.

    PHP框架应用和发展.pdf PHP内核介绍及扩展开发指南.pdf php mysql网上购物系统毕业设计资料.pdf PHP和MySQL Web应用开发.pdf php基础教程-绝对推荐.pdf 入门教程PHP资料.pdf Sulzer-PHP 中文用户(操作)说明书.pdf ...

    PHP轻量级框架

    毕业设计用过的开发框架,十分轻量方便,非常推荐入门PHP的新手去学习。

    PHP入门到精通

    第1篇 基础知识 1.初识PHP(教学录像:23分42秒) 1.1PHP概述 1.2扩展库 1.3前期准备工作 1.4网站建设的基本流程 1.5PHP的学习资源 1.6如何学好PHP ...27.15订单管理模块设计 27.16开发的常见问题 27.17发布网站

    PHP-MSF 入门教程之服务&路由&应用

    PHP微服务框架即“Micro Service Framework For PHP”,是Camera360社区服务器端团队基于Swoole自主研发现代化的PHP协程服务框架,简称msf或者php-msf,是Swoole的工程级企业应用框架,经受了Camera360亿级用户高...

    PHP入门到精通02

    第1篇 基础知识 1.初识PHP(教学录像:23分42秒) 1.1PHP概述 1.2扩展库 1.3前期准备工作 1.4网站建设的基本流程 1.5PHP的学习资源 1.6如何学好PHP ...27.15订单管理模块设计 27.16开发的常见问题 27.17发布网站

    84PHP开源框架 v2.2.1

    84PHP是一套完全遵守APACHE开源协议的便捷PHP框架,独特的模块化设计,使得框架简洁易懂。一行代码即可完成在线支付、发送短信、分页等功能,前所未有的简单和高效!本框架的入门指南位于源码包内根目录下的Readme....

    MyQEE开源PHP多项目及模块化开发框架 v3.0 RC2

    关于MyQEEMyQEE是一个开源、快速、优雅的轻量级PHP框架,支持HMVC模式,建立在PHP5.2基础之上,支持多项目管理开发,数据库内置自动主从分离功能,MySQL支持事务操作功能并且支持自动嵌套功能,多驱动设计灵活适应...

    jungle:丛林PHP框架

    丛林PHP框架(JF) v0.1.6框架遵循以下通用标准: 层次MVC(hmvc)架构基于属性的访问控制(ABAC)标准用于访问控制ORM支持全局可重用对象,模式继承,动态класса схемы字段和связей 从MCA系统中的...

    JeCat PHP Toolbox v0.1.1 Alpha 4

    并且 JeCat PHP Toolbox 与 JCAT PHP 框架 集成的非常好,她几乎就是为 JCAT PHP 框架 设计的。使用 JeCat PHP Toolbox 的理由:1、你不想再重复着 将一些千篇一律的代码 从一些文件 复制/粘贴 的另一些文件;那些...

    MyQEE开源PHP多项目及模块化开发框架 v3.0 RC2.zip

    MyQEE是一个开源、快速、优雅的轻量级PHP框架,支持HMVC模式,建立在PHP5.2基础之上,支持多项目管理开发,数据库内置自动主从分离功能,MySQL支持事务操作功能并且支持自动嵌套功能,多驱动设计灵活适应各种环境。...

    PHP和MySQL Web应用开发核心技术 源码

    ·介绍计划Web应用程序,包括用户界面和用户管理。 ·提供关于保证Web应用程序安全性的系统化指南。 ·涵盖广泛的实现问题——包括国际化、错语处理、数据验证、调试、会话管理和部署。 ·关于XML、基于XML的Web服务...

    Dream项目管理系统 v1.1.rar

    Dream项目管理系统(又称:梦想项目管理系统)是一款基于PHP Mysql开发的一款Bug管理系统,系统内置项目管理、bug提交、bug百科、出差**志、用户管理、组别管理、部门管理,同时系统还能动态开启子公司,当您的公司...

    Dream项目管理系统 v1.1.zip

    Dream项目管理系统(又称:梦想项目管理系统)是一款基于PHP Mysql开发的一款Bug管理系统,系统内置项目管理、bug提交、bug百科、出差日志、用户管理、组别管理、部门管理,同时系统还能动态开启子公司,当您的公司...

    POSCMS开源内容管理系统 v3.2.0 bulid1118

    简称POSCMS)以开放、开源、灵活为产品理念,基于PHP+MYSQL+CI框架开发的开源Web内容管理系统,程序完美兼容PHP7,并在PHP7基础上做了性能优化,系统更加稳定,操作人性化、功能强大、扩展性强,二次开发及后期维护...

    梦赢开源权限管理系统 v2.0.rar

    以前做web应用,每次开发新项目都要重新搭建框架、重复的去做用户管理、系统管理、权限管理等页面,耗时间、耗人力、成本高。 现在做web应用,上面的事您都不用重复做了,您只要做的就是,专心开发您的项目,精力...

    Laravel框架关键技术解析

    《Laravel框架关键技术解析》第1章到第4章主要介绍了与Laravel框架学习相关的基础部分,读者可以深入了解该框架的设计思想,学习环境搭建,了解PHP语法知识和HTTP协议;第5章到第14章分别从某个方面介绍Laravel框架...

    梦赢开源权限管理系统 v2.0.zip

    以前做web应用,每次开发新项目都要重新搭建框架、重复的去做用户管理、系统管理、权限管理等页面,耗时间、耗人力、成本高。   现在做web应用,上面的事您都不用重复做了,您只要做的就是,专心开发您的项目,...

    laravel-modular-starter:Laravel模块设计模式入门套件

    关于Laravel模块化入门套件Laravel模块化入门工具包是laravel框架入门工具包,用于模块化设计模式,优雅的语法。 Laravel入门套件是根据的开源软件。要求PHP 7.4或更高版本如何使用制作模块 php artisan module:make...

    迅睿CMS免费开源系统 v4.3.3

    CodeIgniter 安装包中包含《用户手册》,手册囊括了入门介绍、教程、“手把手”指导,还包括了框架组件的参考文档。二、效率与安全1、运用全新PHP7语法特性,设计时考虑到性能优化,运行效率高达4倍于PHP5系列开发...

Global site tag (gtag.js) - Google Analytics