php网站怎么注入_php网站怎么注入数据库
- 时间:
- 浏览:0
php网站怎么注入_php网站怎么注入数据库
好久不见了各位,今天我想跟大家探讨一下关于“php网站怎么注入”的问题。如果你还不了解这方面的内容,那么这篇文章就是为你准备的,请跟我一起来探索一下。
文章目录列表:
1.[php]这个注入函数怎么用,放在哪里
2.PHP中什么是依赖注入
3.PHP网站怎么sql注入?有没有_防御的方法?
4.php网站怎么注入php注入
5.PHP代码网站如何防范SQL注入漏洞攻击建议分享
6.php做的网站,留言板块mysql数据库被注入,已经有验证码了,但是还是被注入,请问该怎么办?
[php]这个注入函数怎么用,放在哪里
应该是调用,在页面传值进来时进行调用;
如:
$id=unsqlin("$_post['传入框的名字']");
要是防SQL注入,其实可以使用mysql_escape_string()这个函数。方法和上面的一样。
PHP中什么是依赖注入
依赖注入可能是我所知道的_简单设计模式之一,很多情况下可能你无意识中已经使用了依赖注入。不过它也是_难解释的一个。我认为有一部分原因是由于大多数介绍依赖注入的例子缺乏实际意义,让人难理解。因为PHP主要用于Web开发,那就先来看一个简单的web开发实例。
HTTP本身是一个无状态的连接协议,为了支持客户在发起WEB请求时应用程序能存储用户信息,我们就需要通过一种技术来实现存储状态交互。理所当然_简单的是使用cookie,更好的方式是PHP内置的Session机制。
$_SESSION['language']='fr';
上面代码将用户语言存储在了名为language的Session变量中,因此在该用户随后的请求中,可以通过全局数组$_SESSION来获取language:
$user_language=$_SESSION['language'];
依赖注入主要用于面向对像开发,现在让我们假设我们有一个Sessi_torage类,该类封装了PHP Session机制:
class Sessi_torage
{
function __c_truct($cookieName='PHP_SESS_ID')
{
session_name($cookieName);
session_start();
}
function set($key, $value)
{
$_SESSION[$key]=$value;
}
function get($key)
{
return $_SESSION[$key];
}
// ...
}
同时还有一个User类提供了更_的封装:
class User
{
protected $storage;
function __c_truct()
{
$this->storage=new Sessi_torage();
}
function setLanguage($language)
{
$this->storage->set('language', $language);
}
function getLanguage()
{
return $this->storage->get('language');
}
// ...
}
代码很简单,同样使用User类也很简单:
$user=new User();
$user->setLanguage('fr');
$user_language=$user->getLanguage();
一切都很美好,除非你的程序需要更好的扩展性。假设现在你想要更改保存session_id的COOKIE键值,以下有一些可供选择的方法:
User类中创建Sessi_torage实例时,在Sessi_torage构造方法中使用字符串’SESSION_ID’硬编码:
class User
{
function __c_truct()
{
$this->storage=new Sessi_torage('SESSION_ID');
}
// ...
}
在User类外部设置一个常量(名为STORAGE_SESSION_NAME)
class User
{
function __c_truct()
{
$this->storage=new Sessi_torage(STORAGE_SESSION_NAME);
}
// ...
}
define('STORAGE_SESSION_NAME', 'SESSION_ID');
通过User类构造函数中的参数传递Session name
class User
{
function __c_truct($sessionName)
{
$this->storage=new Sessi_torage($sessionName);
}
// ...
}
$user=new User('SESSION_ID');
还是通过User类构造函数中的参数传递Session name,不过这次参数采用数组的方式
class User
{
function __c_truct($storageOpti_)
{
$this->storage=new Sessi_torage($storageOpti_['session_name']);
}
// ...
}
$user=new User(array('session_name'=> 'SESSION_ID'));
上面的方式都很糟糕。
在user类中硬编码设置session name的做法没有真正解决问题,如果以后你还需要更改保存session_id的COOKIE键值,你不得不再一次修改user类(User类不应该关心COOKIE键值)。
使用常量的方式同样很糟,造成User类依赖于一个常量设置。
通过User类构造函数的参数或数组来传递session name相对来说好一些,不过也不_,这样做干扰了User类构造函数的参数,因为如何存储Session并不是User类需要关心的,User类不应该和它们扯上关联。
另外,还有一个问题不太好解决:我们如何改变Sessi_torage类。这种应用场景很多,比如你要用一个Session模拟类来做测试,或者你要将Session存储在数据库或者内存中。目前这种实现方式,在不改变User类的情况下,很难做到这点。
现在,让我们来使用依赖注入。回忆一下,之前我们是在User类内部创建Sessi_torage对像的,现在我们修改一下,让Sessi_torage对像通过User类的构造函数传递进去。
class User
{
function __c_truct($storage)
{
$this->storage=$storage;
}
// ...
这就是依赖注入_经典的案例,没有之一。现在使用User类有一些小小的改变,首先你需要创建Sessi_torage对像。
$storage=new Sessi_torage('SESSION_ID');
$user=new User($storage);
现在,配置session存储对像很简单了,同样如果改变session存储对像也很简单,所有这一切并不需要去更新User类,降低了业务类之间的耦合。
Pico Container 的网站上是这样描述依赖注入:
依赖注入是通过类的构造函数、方法、或者直接写入的方式,将所依赖的组件传递给类的方式。
所以依赖注入并不只限于通过构造函数注入。下面来看看几种注入方式:
构造函数注入
class User
{
function __c_truct($storage)
{
$this->storage=$storage;
}
// ...
}
setter方法注入
class User
{
function setSessi_torage($storage)
{
$this->storage=$storage;
}
// ...
}
属性直接注入
class User
{
public $sessi_torage;
}
$user->sessi_torage=$storage;
根据经验,一般通过构造函数注入的是强依赖关系的组件,setter方式用来注入可选的依赖组件。
现在,大多数流行的PHP框架都采用了依赖注入的模式实现业务组件间的高内聚低耦合。
// symfony: 构造函数注入的例子
$dispatcher=new _EventDispatcher();
$storage=new _MySQLSessi_torage(array('database'=> 'session', 'db_table'=> 'session'));
$user=new _User($dispatcher, $storage, array('default_culture'=> 'en'));
// Zend Framework: setter方式注入的例子
$transport=new Zend_Mail_Transport_Smtp('smtp.gmail.com', array(
'auth'=> 'login',
'username'=> 'foo',
'password'=> 'bar',
'ssl'=> 'ssl',
'port'=> 465,
));
$mailer=new Zend_Mail();
$mailer->setDefaultTransport($transport);
PHP网站怎么sql注入?有没有_防御的方法?
网站的运行安全肯定是每个站长必须考虑的问题,大家知道,大多数黑客攻击网站都是采用sql注入,这就是我们常说的为什么_原始的静态的网站反而是_安全的。 今天我们讲讲PHP注入的安全规范,防止自己的网站被sql注入。
如今主流的网站开发语言还是php,那我们就从php网站如何防止sql注入开始说起:
Php注入的安全防范通过上面的过程,我们可以了解到php注入的原理和手法,当然我们也同样可以制定出相应该的防范方法:
首先是对服务器的安全设置,这里主要是php+mysql的安全设置和linux主机的安全设置。对php+mysql注射的防范,首先将magic_quotes_gpc设置为On,display_errors设置为Off,如果id型,我们利用intval()将其转换成整数类型,如代码:
$id=intval($id);
mysql_query=”select *from example where articieid=’$id’”;或者这样写:mysql_query(”SELECT * FROM article WHERE articleid=”.intval($id).”")
如果是字符型就用addslashes()过滤一下,然后再过滤”%”和”_”如:
$search=addslashes($search);
$search=str_replace(“_”,”\_”,$search);
$search=str_replace(“%”,”\%”,$search);
当然也可以加php通用防注入代码:
/*************************
PHP通用防注入安全代码
说明:
判断传递的变量中是否含有非法字符
如$_POST、$_GET
功能:
防注入
**************************/
//要过滤的非法字符
$ArrFiltrate=array(”‘”,”;”,”union”);
//出错后要跳转的url,不填则默认前一页
$StrGoUrl=”";
//是否存在数组中的值
function FunStringExist($StrFiltrate,$ArrFiltrate){
foreach ($ArrFiltrate as $key=>$value){
if (eregi($value,$StrFiltrate)){
return true;
}
}
return false;
}
//合并$_POST 和 $_GET
if(function_exists(array_merge)){
$ArrPostAndGet=array_merge($HTTP_POST_VARS,$HTTP_GET_VARS);
}else{
foreach($HTTP_POST_VARS as $key=>$value){
$ArrPostAndGet[]=$value;
}
foreach($HTTP_GET_VARS as $key=>$value){
$ArrPostAndGet[]=$value;
}
}
//验证开始
foreach($ArrPostAndGet as $key=>$value){
if (FunStringExist($value,$ArrFiltrate)){
echo “alert(/”Neeao提示,非法字符/”);”;
if (empty($StrGoUrl)){
echo “history.go(-1);”;
}else{
echo “window.location=/”".$StrGoUrl.”/”;”;
}
exit;
}
}
>/*************************
保存为checkpostandget.php
然后在每个php文件前加include(“checkpostandget.php“);即可
**************************/
另外将管理员用户名和密码都采取md5加密,这样就能有效地防止了php的注入。
还有服务器和mysql也要加强一些安全防范。
对于linux服务器的安全设置:
加密口令,使用“/usr/sbin/authconfig”工具打开密码的shadow功能,对password进行加密。
禁止访问重要文件,进入linux命令界面,在提示符下输入:
#chmod 600 /etc/inetd.conf //改变文件属性为600
#chattr +I /etc/inetd.conf //保证文件属主为root
#chattr –I /etc/inetd.conf // 对该文件的改变做限制
禁止任何用户通过su命令改变为root用户
在su配置文件即/etc/pam.d/目录下的开头添加下面两行:
Auth sufficient /lib/security/pam_rootok.so debug
Auth required /lib/security/pam_whell.so group=wheel
删除所有的特殊帐户
#userdel lp等等 删除用户
#groupdel lp等等 删除组
禁止不使用的suid/sgid程序
#find / -type f \(-perm -04000 - o –perm -02000 \) \-execls –lg {} \;
php网站怎么注入php注入
如何将sql注入PHP网站?有办法_防御吗?
网站的运行安全是每个站长必须考虑的问题。众所周知,黑客攻击网站大多采用sql注入的方式,这也是为什么我们常说_原始、_静态的网站是_安全的。今天我们来谈谈PHP注入的安全规范,防止你的网站被sql注入。当今主流的网站开发语言是php,那么我们先从php网站如何防范sql注入说起:
php注入的安全注意事项通过以上过程,我们可以学习Php注入的原理和技巧,当然也可以制定出相应的注意事项:
首先是服务器的安全设置,这里有phpmysql的安全设置和linux主机的安全设置。为了防止phpmysql注入,首先将magic_quotes_gpc设置为on,display_errors设置为Off。如果是id类型,我们用intval()将其转换成整数类型,比如代码:
$id=intval($id);
MySQL_query="select*fromexamplewherearticleid='$id'";或者这样写:MySQL_query("select*fromarticlewherearticleleid="。intval($id)。"")
如果是字符型,用addslashes()过滤,再过滤“%”和“_”,比如:
$search=addslashes($search);
$search=str_replace("_","_",$search);
$search=str_replace("%","%",$search);
当然,你也可以添加php通用反注入代码:
/*************************
通用PHP反注入安全代码
描述:
确定传递的变量是否包含非法字符。
比如$_POST,$_GET
功能:
反注射
**************************/
//要过滤的非法字符
$ArrFiltrate=array(“”,“;”,“工会”);
//出错后要跳转的url。如果留空,则默认为上一页。
$StrGoUrl="
//数组中是否有值
函数FunStringExist($strfilter,$ArrFiltrate
foreach($arrfilteras$key=$value){
if(eregi($value,$StrFiltrate)){
返回true
}
}
返回false
}
//合并$_POST和$_GET
if(function_exists(array_merge)){
$ArrPostAndGet=array_merge($HTTP_POST_VARS,$HTTP_GET_VARS);
}否则{
foreach($HTTP_POST_VARSas$key=$value){
$ArrPostAndGet[]=$value;
}
foreach($HTTP_GET_VARSas$key=$value){
$ArrPostAndGet[]=$value;
}
}
//身份验证开始。
foreach($ArrPostAndGetas$key=$value){
if(FunStringExist($value,$ArrFiltrate
Echo"alert(/"Neeao提示,非法字符/");
if(empty($StrGoUrl)){
echo"history.go(-1);";
}否则{
echo“window.location=/”quot;.$StrGoUrl。"/";";
}
退出;
}
}
马鞭你可以。
**************************/
另外,管理员用户名和密码采用md5加密,可以有效防止php的注入。
还有一些服务器和mysql的安全防范措施。
linux服务器的安全设置:
加密密码,使用“/usr/sbin/authconfig”工具打开密码的影子功能,加密密码。
禁止访问重要文件,进入linux命令界面,输入:
#chmod600/etc/inetd.conf//将文件属性更改为600
#chattrI/etc/inetd.conf//确保文件的所有者是root
##chattr-I/etc/inetd.conf////限制对此文件的更改
禁止任何用户通过su命令更改为root用户。
在su配置文件的开头添加以下两行,即/etc/pam.d/directory:
authsufficient/lib/security/PAM_rootok.sodebug
需要授权/lib/security/PAM_whell.sogroup=wheel
删除所有特殊账户。
#userdellp等。删除用户
#groupdellp等。删除该组
禁止的suid/sgid程序
#find/-键入f)-execls_LG{};
如何判断PHP源码是否存在SQL注入漏洞?
判断是否存在SQL注入首先找到可能的注入点;比如常见的get,post,甚至cookie,传递参数到PHP,然后参数被拼接到SQL中,如果后端接收参数后没有进行验证过滤,就很可能会出现注入。比如xxx.com?id=321,id就很可能是注入点。
说白了就是不要相信用户输入,对用户可控的参数进行严格校验。注意是严格校验!简单的去空格,或者是特殊字符替换很容易绕过。
如果已经有原码,可以进行代码审计,进行逐一排查。也可以搭建本地环境使用类似于sqlmap这样的自动化工具进行可以链接的检测。
个人理解仅供参考,如有偏颇望批评指正!
PHP代码网站如何防范SQL注入漏洞攻击建议分享
做为网络开发者的你对这种黑客行为恨之入骨,当然也有必要了解一下SQL注入这种功能方式的原理并学会如何通过代码来保护自己的网站数据库。今天就通过PHP和MySQL数据库为例,分享一下我所了解的SQL注入攻击和一些简单的防范措施和一些如何避免SQL注入攻击的建议。
简单来说,SQL注入是使用代码漏洞来获取网站或应用程序后台的SQL数据库中的数据,进而可以取得数据库的访问权限。比如,黑客可以利用网站代码的漏洞,使用SQL注入的方式取得一个公司网站后台数据库里所有的数据信息。拿到数据库管理员登录用户名和密码后黑客可以自由修改数据库中的内容甚至删除该数据库。SQL注入也可以用来检验一个网站或应用的安全性。SQL注入的方式有很多种,但本文将只讨论_基本的原理,我们将以PHP和MySQL为例。本文的例子很简单,如果你使用其它语言理解起来也不会有难度,重点关注SQL命令即可。
一个简单的SQL注入攻击案例
假如我们有一个公司网站,在网站的后台数据库中保存了所有的客户数据等重要信息。假如网站登录页面的代码中有这样一条命令来读取用户信息。
$q="SELECT `id` FROM `users` WHERE `username`=' " .$_GET['username']. " ' AND `password`=' " .$_GET['password']. " ' ";?>现在有一个黑客想攻击你的数据库,他会尝试在此登录页面的用户名的输入框中输入以下代码:
' ; SHOW TABLES;
点击登陆键,这个页面就会显示出数据库中的所有表。如果他现在使用下面这行命令:
'; DROP TABLE [table name];
这样他就把一张表删除了!
防范SQL注入 - 使用mysql_real_escape_string()函数
在数据库操作的代码中用这个函数mysql_real_escape_string()可以将代_殊字符过滤掉,如引号等。如下例:
$q="SELECT `id` FROM `users` WHERE `username`=' " .mysql_real_escape_string( $_GET['username'] ). " ' AND `password`=' " .mysql_real_escape_string( $_GET['password'] ). " ' ";?>防范SQL注入 - 使用mysql_query()函数
mysql_query()的特别是它将只执行SQL代码的_条,而后面的并不会执行。回想在_前面的例子中,黑客通过代码来例后台执行了多条SQL命令,显示出了所有表的名称。所以mysql_query()函数可以取到进一步保护的作用。我们进一步演化刚才的代码就得到了下面的代码:
//connection
$database=mysql_connect("localhost", "username","password");
//db selection
$q=mysql_query("SELECT `id` FROM `users` WHERE `username`=' " .mysql_real_escape_string( $_GET['username'] ). " ' AND `password`=' " .mysql_real_escape_string( $_GET['password'] ). " ' ", $database);?>除此之外,我们还可以在PHP代码中判断输入值的长度,或者专门用一个函数来检查输入的值。所以在接受用户输入值的地方一定要做好输入内容的过滤和检查。当然学习和了解_新的SQL注入方式也非常重要,这样才能做到有目的的防范。如果使用的是_式的网站系统如Wordpress,要注意及时打上官方的补丁或升级到新的版本。
php做的网站,留言板块mysql数据库被注入,已经有验证码了,但是还是被注入,请问该怎么办?
字符串型数据(比如姓名、****)用addslashes函数来过滤,数字类型数据用intval来过滤
比如你要提交的表单姓名为name,****为tel,邮箱为mail,留言为msg。举例代码如下:
<?php$name?=?isset($_REQUEST['name'])addslashes($_REQUEST['name'])?:?'匿名';
$tel?=?isset($_REQUEST['tel'])addslashes($_REQUEST['tel'])?:?'匿名';
$mail?=?isset($_REQUEST['mail'])addslashes($_REQUEST['mail'])?:?'匿名';
$msg?=?isset($_REQUEST['msg'])addslashes($_REQUEST['msg'])?:?'匿名';
>然后你再把这四个变量拼接到sql字串里面就不会被注入了
php依赖注入是在构造函数中注入吗
PHP 依赖注入
tags: dependency injection,php
by Ryan on January 8, 2009
Dependency injection is the answer to more maintainable, testable, modular code.
依赖注入是对于要求更易维护,更易测试,更加模块化的代码的答案。
Every project has dependencies and the more complex the project is the more dependencies it will most likely have. The most common dependency in today’s web _lication is the database and chances are if it goes down the _ will all together stop working. That is because the code is dependent on the database server… and that is perfectly fine. Not using a database server because it could one day crash is a bit ridiculous. Even though the dependency has its flaws, it still makes life for the code, and thus the developer, a lot easier.
每个项目都有依赖(外界提供的输入), 项目越复杂,越需要更多的依赖。在现今的网络应用程序中,_常见的依赖是数据库,其风险在于,一旦数据库暂停运行,那么整个程序也因此而停止运行。这是因为代码依赖数据库服务器。。。这已足够。因为数据库服务器有时会崩溃而弃用它是荒谬的。尽管依赖有其自身的瑕疵,它仍然使代码,因而也使程序开发人员的生活更容易些。
The problem with most dependencies its the way that code handles and interacts with them, meaning, the problem is the code and not the dependency. If you are not using dependency injection, chances are your code looks something like this:
对于大多依赖而言,问题在于代码如何处理它们及与它们交往。也就是说,问题是代码本身而非依赖。如果你没有使用依赖注入,有机会遇到下列代码:
class Book {
publicfunction __c_truct(){
$registry=RegistrySingleton::getInstance();
$this->_databaseConnection=$registry->databaseConnection;
// or
global$databaseConnection;
$this->_databaseConnection=$databaseConnection;
}
}
The book object now is given full access to the database once it is c_tructed. That is good, the book needs to be able to talk to the database and pull data. The problem lies in the way the book gained its access. In order for the book to be able to talk to the database the code must have an outside_ariable named $databaseConnection, or worse, it must have a singleton pattern class (registry) object containing a record for a databaseConnection. If these don’t exist the book fails, making this code is far from modular.
现在对象book一旦建立,就已经完全连到数据库。这没什么不好,book需要跟数据库交谈并取得数据。问题在于book取得其接入的方法。要使book能够与数据库交谈,代码必须有一个外来的变量$databaseConnect, 更糟糕的是,它必须有个singleton类型类(registry)的对象,其包含一个databaseConnection的记录。如果这些不存在的话,book会无法运行,这就使得这些代码远远不够模块化。
This raises the question, how exactly does the book get access to the database? This is where inversion of control comes in.
这就提出一个问题,到底book如何接入数据库?这就是IoC出现的原因了。
In Hollywood a struggling actor does not call up Martin Scorsese and ask for a role in his next film. No, the opposite h_ens. Martin Scorsese calls up the broke actor and asks him to play the main character in his next movie. Objects are struggling actors, they do not get to pick the roles they play, the director needs to tell them what to do. Objects do not get to pick the outside systems they interact with, instead, the outside systems are given to the objects. Remember this as Inversion of Control: The Hollywood Way.
在好莱坞,一个濒临绝境的演员不会打电话给Martin Scoresese要求在他的下个影片中扮演一个角色。绝不会这样,实际正相反。Martin Scorese 会打电话给这个困顿的演员并邀请他在下一部影片中扮演重要的角色。对象是挣扎中的演员,他们不会去捡自己所扮演的角色,导演需要告诉他们去做什么。对象不会到它所接触的外界挑选系统,相反,外界系统会被赋予对象。记住这就是IoC( Inversion of Control):好莱坞的做法。
This is how a developer tells his objects how to interact with outside dependencies:
如下是开发人员告诉他的对象如何与外界的依赖打交道:
class Book {
publicfunction __c_truct(){}
publicfunction setDatabaseConnection($databaseConnection){
$this->_databaseConnection=$databaseConnection;
}
}
$book=new Book();
$book->setDatabase($databaseConnection);
This code allows for the book class to be used in any web _. The Book is no longer dependent on anything other than the developer supplying a database shortly after object creation.这代码允许这个book类能在任何的网页程序中使用。此book不再依赖任何事项,除了程序开发者要在对象创建后立即要提供一个数据库。
This is, at its finest, dependency injection. There are two common practices of injecting dependencies. The first being c_tructor injection and the second being setter injection. C_tructor injection involves passing all of the dependencies as arguments when creating a new object. The code would look something like this:
这就是_方法—依赖注入。有两种常用的依赖注入的方式。一种是 c_tructor (注:构造函数。这种译法似乎并不恰当,类中此方法更多是用来对某些属性进行初始化)注入,一种是setter 注入。C_tructor注入涉及到将所有依赖作为参数,传递给新创建的对象。看起来像这样:
$book=new Book($databaseConnection,$configFile);
The more dependencies an object has, the messier this c_truction becomes. There are other reas_ why this is a bad _roach, involving ideas around code reusability and c_tructors doing work.
对象的依赖越多,c_truction就会变得越杂乱。这里还有其他的原因为什么这是一个坏方法,其涉及到包括代码重用和c_tructors要做的工作。
This leaves us with other method of dependency injection, called setting injection, which involves creating a public method inside the object for the dependencies that need injection.
这就给我们留下其他的方法进行依赖注入,称为设置注入,包含在需要注入依赖的对象里创建一个公共方法:
$book=new Book();
$book->setDatabase($databaseConnection);
$book->setConfigFile($configFile);
This is easy to follow, but it leads writing more and more code for your _lication. When a book object is created three lines of code are required. If we have to inject another dependency, a 4th line of code is now needed. This gets messy quickly.
这很容易实现,但是它会导致为您的程序写大量代码。当创建一个book对象时,需要三行代码。如果我们必须注入另外的依赖时,必须增加第四行代码。这很快变得一团糟。
The answer to this problem is a factory, which is class that is designed to create and then inject all the dependencies needed for an object. Here is an example:
此问题的对策是一个工厂factory,它是一个类,用来创建然后注入一个对象的所有依赖。举例如下:
class Factory {
public static $_database;
public static function makeBook(){
$book=new Book();
$book->setDatabase(self::$_database);
// more injection...(更多注入)
return$book;
}
}
And then:
然后:
$book=Factory::makeBook();
All dependencies should be registered into the factory object during run time. This object is now the gateway that all dependencies must pass through before they can interact with any classes. In other words, this is the dependency container.
所有的依赖在运行期间都应在此factory对象中注册。它现在是大门,在依赖可以与任何对象打交道前,都必经此门。
The reason makeBook is a public static function is for ease of use and global access. When I started this article off I made a reference to the singleton pattern and global access being a poor choices of code. They are… for the most part. It is bad design when they control access, but it is perfectly ok when they control creation. The makeBook function is only a shortcut for creation. There is no dependency what-so-ever between the book class and the factory class. The factory class exists so we can contain our dependencies in one location and automatically inject those dependencies with one line of code creation.
makeBook作为一个静态方法的原因是易用并且可以在全局得到。在本文开头,我提出使用singleton类型和全局变量对代码而言是一个糟糕的选择。多数情形下,确实如此!当他们控制接入时,是一个差设计。但是在他们控制创建时,是一个不错的选择。makeBook方法仅仅是创建的一个捷径。在book类和factory类之间,没有任何依赖。由于factory类的存在,我们的依赖可以存放在一个地点,并且用一行创建代码就可自动注入这些依赖。
The factory or container class removes all of the extra work of dependency injection.
此处的factory或者容器类移走了依赖注入的所有额外工作。
Before injection:
以前的注入:
$book=new Book();
And now:
目前的方法:
$book=Factory::makeBook();
Hardly any extra work, but t_ of extra benefits.
几乎没有任何的额外工作,但是有大量益处。
When test code is run, specifically unit tests, the goal is to see if a method of a class is working correctly. Since the book class requires database access to read the book data it adds a whole layer of complexity. The test has to acquire a database connection, pull data, and test it. All of a sudden the test is no longer testing a single method in the book class, it is now also testing database. If the database is offline, the test would fail. This is FAR from the goal a unit test.当运行测试代码时,尤其是单元测试,其目标是检查类中的方法是否正确地工作。由于book类要求接入数据库并且读取图书数据,它增加了一层复杂度。此测试不得不进行数据库连接,取得数据,然后测试它。瞬间,测试不再是测试book类中的单个方法,它目前同时也测试数据库。如果数据库离线,测试就会失败。这已经远离了单元测试的目的。
A way of dealing with this is just using a different database dependency for the unit tests. When the test suite starts up a dummy database is injected into the book. The dummy database will always have the data the developer expects it to have. If a live database was used in a unit test the data could potentially change causing tests to unnecessarily fail. There is no need for a unit test to be refactored when a record in a database changes.
解决上述问题的方法是用不同的数据库依赖来作单元测试。当测试套件开始时,虚拟的数据库被注入book.虚拟数据库将永远拥有开发人员所期待的数据。如果使用一个真实数据库,数据的潜在变化会导致测试不必要的失败。当数据库的记录改变了,不需因此重新进行单元测试。
The code is more modular because it can dropped into any other web _lication. Create the book object and inject a database connection with $book->setDatabase(). It does not matter if the database is in Registery::Database, $database, or $someRandomDatabaseVarible. As long as there is a database connection the book will work inside any system.
此代码现在更加模块化,因为它可以被放到任何其他的网页程序。创建book对象并且用$book->setDatabase()注入数据库连接。此时,数据库在 Registery::Database, $database,或者$someRandomDatabaseVarible都无关大局。只要有一个数据库连接,book就可以在任何系统内工作。
The code is more maintainable because each object given exactly what it needs. If separate database connecti_ are required between different instances of the same class then there no extra code needed inside the class what-so-ever. Give book1 access to database1 and book2 access to database2.
代码更加易维护,因为每个对象都被赋予了它的所需。如果同一类的实例需要不同的数据库连接,在类内部一点儿也不需要额外的代码。例如book1连接到数据库1,book2连接到数据库2
Factory::$_database=$ourDatabaseVarForDB1;
$book1=Factory::makeBook();
$book2=Factory::makeBook();
$book2->setDatabase($database2);
Dependency injection really is the answer to more maintainable, testable, modular code.
依赖注入真的是更易维护,更易测试和更加模块化的答案。
好了,关于“php网站怎么注入”的话题就讲到这里了。希望大家能够通过我的讲解对“php网站怎么注入”有更全面、深入的了解,并且能够在今后的工作中更好地运用所学知识。