Drupal配置迁移详细讨论

 更新时间:2016年11月25日 17:21  点击:2048
因为drupal的开源、强大、安全等很多优点,因此被业界广泛接受,应用也越来越广范了,可能很多phper会遇到drupal的迁移与配置的问题,现在本人根据自己的经验把这个问题记录下来,供大家参考。

Drupal 配置迁移是什么?很多 Drupaller 对这个话题感到无所适从,新人工作之初并不会意识到这个问题的存在,而意识到这个问题的朋友也不确定怎样正确地进行配置迁移。本文就围绕 Drupal 配置迁移的原因、方式/方法及相关模块较为系统地聊聊这个话题。

Drupal Migrate

如果你被以下问题困扰,仔细阅读本文将会对你有所助益

修改了一些站点配置(如站点名称、标语或任何存在于variables表中的变量值),怎么一次性部署到线上?怎么跟踪每次的修改记录?(大部分情况下你是不是直接在线上修改了:D)

在开发环境中页面布局进行了调整,修改了区块的配置(如位置、显示条件)和内容,怎么样才能快速地部署到线上(是不是手动一个一个去调整,把做过的事情重新再做一遍——这样很无趣,也很费时,还容易遗漏和出错,尤其是当这些配置之前是由其它人配置的,想要再准确地复现将会非常困难)

在开发环境中添加了几个新的字段、内容类型、输入格式、Wysiwyg配置或者视图,不想在线上再手动操作,点鼠标点到手发麻,又应该怎么办?

开发过程中需要大量实际数据,不能直接在线上操作,如何把实际数据从线上迁移到开发环境中?

……

为什么 Drupal 要做配置迁移?

大家都熟悉传统的Web开发,主要工作都是面对代码,不管是PHP、CSS、HTML或JS,几乎所有的工作都是在文件中完成。如果要更新或升级某些功能,做好备份后上传修改过的文件就能完成,So Easy!

对Drupal而言,配置迁移就不那么简单了,因为文件迁移只是 Drupal 配置迁移的一小部分,Drupal 中大部分的配置存在于数据库中。而因为线上环境的数据库时刻在变化,要把开发环境中一部分数据库的内容更新到线上而又不影响线上的内容,可不是一件容易的事。

Drupal configuration in database

Drupal将配置存在于数据库中是经常被Drupal老手们诟病的问题之一——最大的缺点是你不能简单地迁移数据库中的某些值或对其实行版本控制,当然这样设计的优点在于方便开发人员进行研发,以及方便使用者通过界面(而不需要修改代码)非常快速地对功能进行调配。(再一次,Drupal选择了灵活性而牺牲了其它东西)

在D8之前,Drupal没有统一的标准来规范大家应该如何存储各自己的配置数据,不同模块的配置格式和存储方式并不相同,因此也就无法通过某种特定的方式一次性迁移出所有配置数据。

(D8开始实施配置管理系统了,从此对配置的管理有了统一的规范和标准,可参见《Drupal 8 配置管理机制及新特性简介》)

而另外一点造成Drupal的配置迁移成为一个难点话题的原因在于,D8之前,Drupal的配置和内容混合存储在数据库中,很难将两者分离开,如果只是通过覆盖数据库的方式来进行操作,无法做到只改变配置而不触及内容,反之亦然。

因为设计上的原因,使得Drupal的配置迁移成了一个难点,针对于它的工作流程和解决方案也就成了一个独立的、不可回避的且颇有意思的话题。

目前有关Drupal配置迁移的处理方式已经非常成熟,D8之前的配置迁移可以参考本文,D8的配置迁移大家去学习其配置管理系统的知识并熟练运用即可。虽然D8之前没有官方统一的标准配置管理体系,但D8配置管理体系的很多理念与本文提及的各种配置迁移方式是相同的,因此学习本文也将会使之后了解D8的配置管理系统变得更为容易一些。

加强 Drupal 配置迁移自动化的优点

相信有很多朋友在做 Drupal 开发时会先在本地做一次,然后到测试环境或生产环境再做一次。当然这也不失为一种方式,对小站点的功能部署还能适用,但对于在线下进行了几周甚至几个月的工作量,再重复做一次的代价可是相当大的——前提还要是每个人都记得整段时间都按什么顺序做了什么配置。

如果大家希望更轻松、更准确、更高效、更简单地完成配置迁移的任务,不妨学会如何让配置迁移更为自行化。

以下是通过各种工具进行自动化配置迁移的一些主要优点:

减轻工作量——大量配置的部署真的可以点鼠标点到手发麻,将大量点击操作简化为上传文件会轻松很多;
降低错误率——人往往是出错的主要原因,让代码来记忆第一步操作可以大大降低出错机率;
版本控制——能够记录每一次配置的变更状况与时间,同时也更容易将配置恢复到某个时间点的备份;
快速部署——站点经不起长时间离线,将数周及数月的更新在数分钟基本数秒钟之内完成会有很爽的成就感;
……
 

Drupal 常见的配置迁移情况

之所以要谈配置迁移,是因为Web项目至少会有两个环境,即工程师的本地开发环境,和在线运行的生产环境。而通常情况下,标准的Web项目会涉及“开发-测试-线上”,即流行的 Dev-Stage-Prod 模型(也有称Dev-Stage-Live),复杂点的情况还会再加上一个QA环境。也正因为如此,才出现了配置迁移的需要。

Dev Stage Prod Environments

在后文中,我们将以 Dev-Stage-Prod 环境模型为来了解 Drupal 的配置迁移方式及方向。因为这正好代表了我们平时的工作流程——工程师在各自的本地进行开发,然后部署到测试环境集中测试,反复修正最后再部署到线上。

Drupal 需要迁移哪些内容以及如何迁移

了解了需要迁移的原因,我们再看看需要迁移的内容。正如前面所说,Drupal 中不同的配置有不同的迁移方式,使用对的工具和对的方法能够达到事半功倍的效果。

迁移项 存储位置 迁移方式
模块、主题 模块、主题文件中 直接上传文件
环境变量 数据库中 结合 Features 结合 Strongarm 模块打包到文件,然后上传
视图、编辑器、内容类型、字段、区块 数据库中 使用 Features 及 Features Extra 等模块打包到文件,然后上传
*术语、用户等配置依赖内容 数据库中 可使用 Features, UUID 及 UUID Features 等模块打包到文件,然后上传。

但建议先添加到线上环境,然后将数据库下载到本地进行开发会更简单,详见下方

不要感觉要记很多东西似的,这里帮你整理一下 —— Drupal 的配置无非就是存在于文件和数据库中,存在文件中的配置很好处理,直接上传就行。而对于存在于数据库中的配置呢?很简单 —— 先转化成文件,然后上传文件。

在举例说明不同配置迁移的最佳实践前,建议大家一定记住下图——代码(配置)由下往上,数据库(内容)由上往下——这是团队协作的基本铁律,以便确保文件和数据库都是由新往旧的方向部署,从源头减少冲突的发生。

代码及内容更新方向

 (很多人在协作时会问这样的问题,说“我在线上修改了视图的配置,然后线下更新了视图的配置文件,这样要怎么更新呢?”这就是典型因为协作流程不规范而产生的人为冲突,一旦按照规范能够约束文件(配置)、数据库(内容)的更新方向,这类问题基本上便不会出现了。)

回到文章开头提到的几个问题,现在再来看看这些配置迁移流程建议:

站点配置或其它变量迁移 – 使用 Features 模块,结合 Strongarm 模块将要跟踪的变量打包到文件中,然后按 Dev->Stage->Prod 的方向进行更新部署
区块配置迁移 – 使用 Features 模块,结合 Features Extra 模块,将区块的配置及内容打包到文件中,然后按 Dev->Stage->Prod 的方向进行更新部署
内容类型、字段、视图、输入格式、编辑器配置等 – 使用 Features 模块(必要时结合Strongarm)将配置打包到文件中,然后按 Dev->Stage->Prod 的方向进行更新部署
内容数据的更新 – 使用 Backup and Migrate 模块或其它方式导出线上环境的数据库,并按 Prod->Stage->Dev 的方向进行内容更新
 

Drupal 配置迁移小结

现在看来,Drupal的配置迁移无非是两部分的内容,一部分已经存在于文件(如模块、主题)中的内容,直接上传文件进行更新即可;另一部分存在于数据库中的部分配置(或内容),即通过Features及其它相关模块先将配置导出到文件中,再按更新文件的操作进行即可。

别看关于 Drupal 配置迁移好像写了不少,主要便是掌握 Features 模块的用法和流程,稍加练习几次就会发现真是非常简单。

当你关注Drupal的时候,说明你已经知道它的强大和魅力,但是,再强大的Drupal,也会有其缺点和不足,今天谈论这个话题,并不是黑Drupal,而是让准备选择Drupal的人更清楚的了解Drupal,然后发挥Drupal的优势。

以下对 Drupal 的一些缺陷和不足进行罗列和说明,并且也提供一些弥补、改善或者避开的方法,这样以后在遇到这些问题的时候能够更从容一些。

易学性与易用性

Drupal 在用户友好的层面上存在两大“不足”,分别是易学性和易用性。

Drupal 易学性上的不足是先天基因决定,它是面向“开发人员”的工具,而非面向普通用户的产品。要基于 Drupal 搭建一个网站或者是系统,普通用户入手之初最多只能安装和配置一些简单的模块,要想做到像熟手们说的那样“找到模块安装一下就好了”,那是不可能的。

如果想要对系统进行修改或者说是扩展,前期没有投入一定的时间去学习和了解 Drupal 的基本知识,除了面对一大片后台管理链接无所适从之外,新手们还能干什么呢?

Drupal 非常不容易学习,因为扩展的灵活性使其拥有了相对其它系统更为复杂的结构,添加新页面应该使用菜单系统、访问数据库应该使用数据库抽象层、添加修改模版要先学习模版机制,原本在其它系统下的经验到 Drupal 上来统统都不能用了 —— 使用 Drupal 的人少,与它的学习曲线、学习周期严重相关。这是 Drupal 的一个先天不足,但这些“化简为繁”的机制和抽象层最终给 Drupal 提供了无比强大、无可比拟的扩展性和灵活性 —— 所以对于慕名而来的 Drupal 的仰慕者们,Drupal 很强大,但必须要在熟练的人的手上,可以花重金请专业的团队打造世界一流的站点和系统,但切不可抓几个 PHPer 就妄想短时间内驾驭这匹野马。

PS: Drupal 功能性和扩展性的强大,以及学习曲线和周期决定了其自身的价值,一分努力一分收获,请走在 Drupal 之路上的各位谨记!!!


与易学性相同,Drupal 的易用性也是先天不足,一方面是因为它不是面向普通用户“开箱即用”的产品,另一方面是因为在用户体验“能用、易用、好用”的三级标准上,Drupal 的功能在很大一部分程度上都只是“能用”的级别。只实现基本的体验和交互,优点在于能够方便地在其之上添加需要的行为,缺点在于没有一个默认易用的行为,每个站点都需要付出一定的工作量。

易用性是 Drupal 的一项不足,但并非硬伤,相对其它一些不易扩展的CMS或者框架,Drupal 至少能够让我们更快的优先获得功能,至于用户体验和交互,对于熟手来讲也是手到擒来的事。

 
因为今天时间有限,后面的一些缺陷与不足先简单介绍一下,后续有需要了解的地方大伙再给我发邮件或者是留言咨询吧,先谢过。

兼容性

Drupal 大版本之间不提供向后兼容,即 D7 不向后兼容 D6,D8 不向后兼容 D7。根据 Dries 若干年前的博客(大概是2005年,记不太清楚了),说明了 Drupal 的新版本会选择同时期最新的技术,以保证 Drupal 走在技术的前沿,同时因为不提供向后的兼容,能够更好的保持核心的精简。

对于需要做大版本升级的个人或公司,在此的第一个建议是不要做大版本升级,因为确实必要性不大,但工作量可能惊人的可怕。如果实在要升级,同样从工作量出发,可以先行评估,然后从升级和重建中做出合适的选择。

性能

Drupal 在扩展性和灵活性之间需要做出平衡,模块化的架构和 hook回调系统则是站在扩展性这一边。强大的扩展性会带来性能上的损耗,但 Drupal 通过内置的缓存系统以及整合各种外部缓存、代理、加速来大幅提升性能。

有关扩展与性能的话题,我们在之前的视频里面有提到过,可以找找看。

 模版抽象层

Drupal 的页面布局更多是通过区域分配的方式来执行,内容与内容框架(确定内容组织方式的HTML代码结构)混合存在一起,传统前端生成 HTML的方式在 Drupal 中难以得以应用。而内容与内容框架混合的形式也使得 Drupal 主题很难像 WordPress 那样做到主题的复用。


团队协作

Drupal 的团队协作应该算是 Drupal 各种抽象层的副作用,因为整个项目流程与传统网站项目不同,所以协作上也会出现一些难点。不过通过对 Drupal 流程有清晰的了解之后,能够找出不同职能的分界线,通过 Drupal 的方式来进行团队协作,问题就能够得以解决了。

SQL注入攻击的概念及危害我相信大家都有所了解,如果不了解的请自己度娘,下面我们来学习一下在php中如何有效的防止

问题描述:

如果用户输入的数据在未经处理的情况下插入到一条SQL查询语句,那么应用将很可能遭受到SQL注入攻击,正如下面的例子:

 代码如下 复制代码
$unsafe_variable = $_POST['user_input'];
 
mysql_query("INSERT INTO `table` (`column`) VALUES ('" . $unsafe_variable . "')");


因为用户的输入可能是这样的:


 代码如下 复制代码
value'); DROP TABLE table;--


那么SQL查询将变成如下:

 代码如下 复制代码
INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')


应该采取哪些有效的方法来防止SQL注入?



最佳回答(来自Theo):

使用预处理语句和参数化查询。预处理语句和参数分别发送到数据库服务器进行解析,参数将会被当作普通字符处理。这种方式使得攻击者无法注入恶意的SQL。 你有两种选择来实现该方法:

1、使用PDO:

 代码如下 复制代码

$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
 
$stmt->execute(array('name' => $name));
 
foreach ($stmt as $row) {
    // do something with $row
}

2、使用mysqli:

 代码如下 复制代码
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name);
 
$stmt->execute();
 
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    // do something with $row
}


PDO

注意,在默认情况使用PDO并没有让MySQL数据库执行真正的预处理语句(原因见下文)。为了解决这个问题,你应该禁止PDO模拟预处理语句。一个正确使用PDO创建数据库连接的例子如下:

$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

在上面的例子中,报错模式(ATTR_ERRMODE)并不是必须的,但建议加上它。这样,当发生致命错误(Fatal Error)时,脚本就不会停止运行,而是给了程序员一个捕获PDOExceptions的机会,以便对错误进行妥善处理。 然而,第一个setAttribute()调用是必须的,它禁止PDO模拟预处理语句,而使用真正的预处理语句,即有MySQL执行预处理语句。这能确保语句和参数在发送给MySQL之前没有被PHP处理过,这将使得攻击者无法注入恶意SQL。了解原因,可参考这篇博文:PDO防注入原理分析以及使用PDO的注意事项。 注意在老版本的PHP(<5.3.6),你无法通过在PDO的构造器的DSN上设置字符集,参考:silently ignored the charset parameter。

解析

当你将SQL语句发送给数据库服务器进行预处理和解析时发生了什么?通过指定占位符(一个?或者一个上面例子中命名的 :name),告诉数据库引擎你想在哪里进行过滤。当你调用execute的时候,预处理语句将会与你指定的参数值结合。 关键点就在这里:参数的值是和经过解析的SQL语句结合到一起,而不是SQL字符串。SQL注入是通过触发脚本在构造SQL语句时包含恶意的字符串。所以,通过将SQL语句和参数分开,你防止了SQL注入的风险。任何你发送的参数的值都将被当作普通字符串,而不会被数据库服务器解析。回到上面的例子,如果$name变量的值为 ’Sarah’; DELETE FROM employees ,那么实际的查询将是在 employees 中查找 name 字段值为 ’Sarah’; DELETE FROM employees 的记录。 另一个使用预处理语句的好处是:如果你在同一次数据库连接会话中执行同样的语句许多次,它将只被解析一次,这可以提升一点执行速度。 如果你想问插入该如何做,请看下面这个例子(使用PDO):

 代码如下 复制代码

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));

单态模式的主要作用是保证在面向对象编程设计中,一个类只能有一个实例对象存在。作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。

1.单态设计模式含义:

单态模式的主要作用是保证在面向对象编程设计中,一个类只能有一个实例对象存在。作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。

2.单台模式的三个关键点:

① 需要一个保存类的唯一实例的静态成员变量;
②构造函数和克隆函数必须声明为私有的,防止外部程序new类从而失去单例模式的意义;
③必须提供一个访问这个实例的公共的静态方法(通常为getInstance方法),从而返回唯一实例的一个引用 。

 

 代码如下 复制代码
<?php
class DB {
private static $obj = null;           //声明一个私有的,静态的成员属性$obj
private function__construct() {       //私有构造方法,只能在类的内部实例化对象
echo "连接数据库成功<br>";
}
public static function getInstance() {  // 通过此静态方法才能获取本类的对象
if(is_null(self::$obj))  //如果本类中的$obj为空,说明还没有被实例化过
self::$obj = new self();  //实例化本类对象
return self::$obj;  //返回本类的对象
}
public function query($sql) {  //执行SQL语句完成对数据库的操作
echo $sql;
}
}
$db = DB::getInstance();        //只能使用静态方法getInstance()去获取DB类的对象
$db -> query("select *from user");       //访问对象中的成员
?>

 

单例模式,就是保持一个对象只存在一个实例。并且为该唯一实例提供一个全局访问点(一般是一个静态的getInstance方法)。单例模式应用场景非常广泛,例如:
数据库操作对象
日志写入对象
全局配置解析对象等
这些场景的共同特征是从业务逻辑上来看运行期间改对象却是

只需要一个实例

不断new多个实例会增加不必要的资源消耗

全局调用便利

下面分别说明这三个方面:

1. 业务上只需要一个实例

以数据库连接对象为例,加入有一个购物网站,有一个MySQL数据库
127.0.0.1:3306
,那么在一个进程中无论我们需要进行多少次针对改数据库的操作,都只需要连接数据库一次,使用相同的数据库连接句柄(MySQL Connection Resource),从业务需求上来看就只需要一个实例。

相反,同样以购物网站为例,存在许多商品,这些商品都不一样(id,name,price..),这个时候需要显示一个商品列表,加入我们建立一个
Product
作为数据映射对象,那么从业务需求上来说,一个实例就无法满足业务需求,因为每个商品都不一样。

2. 不断new操作增加不必要的资源消耗


我们一般会在类的构造方法(new操作肯定会调用)中进行一些业务操作,例如数据库连接对象可能会在构造方法中尝试读取数据库配置并进行数据库连接(如mysqli::__construct())、日志写入对象会判断日志写入目录是否存在并写入(不存在可能尝试创建改目录)、全局配置解析对象可能需要定位配置文件的保存目录并进行文件扫描等。

这些业务都会消耗相当的资源,如果在一个进程中我们值需要做一次,将会非常有利于我们提高应用的运行效率。

3. 全局调用便利

因为单例模式的一大特点就是通过静态方法获取对象实例,那么就意味着访问对象的方法时不需要先new一个对象的实例,如果改对象需要很多地方使用,则提高了调用的便利性。

通过一个日志操作类来举例:

 代码如下 复制代码
class Logger{

    //首先,需要一个私有的静态变量来存储产生的对象实例
    private static $instance;

    //业务变量,保存日志写入路径
    private $logDir;

    //构造方法,注意必须也是私有的,不允许被外部实例化(即在外部被new)
    private function __construct(){
        //调试输出,测试对象被new的次数
        echo "new Logger instance rn";
        $logDir = sys_get_temp_dir(). DIRECTORY_SEPARATOR . "logs";
        if(!is_dir($logDir) || !file_exists($logDir)){
            @mkdir($logDir);
        }
        $this->logDir = $logDir;

    }

    //类唯一实例的全局访问点,用于判断并返回对象实例,供外部调用
    public static function getInstance(){
        if(is_null(self::$instance)){
            $class = __CLASS__; //获取本对象的类型,也可以用new self()方式
            self::$instance = new $class();
        }
        return self::$instance;
    }

    //重载__clone()方法,不允许对象对克隆
    public function __clone(){
        throw new Exception("Singleton Class Can Not Be Cloned");
    }

    //具体的业务方法,实际可以有很多方法
    public function logError($message){
        $logFile = $this->logDir . DIRECTORY_SEPARATOR . "error.log";
        error_log($message, 3, $logFile);
    }
}

//日志调用
$logger = Logger::getInstance();
$logger->logError("An error occured");
$logger->logError("Another error occured");

//或者这样调用
Logger::getInstance()->logError("Still have error");
Logger::getInstance()->logError("I should fix it");

在单例模式中可能遇到一种比较特殊的情况,比如数据库连接对象,对于大型应用来说,很可能需要连接多台数据库,那么不同的数据库公用一个对象可能会产生问题,比如连接的分配、获取
insert_id

last_error
等。这个问题也比较好解决,就是把我们的$instance变量变成一个关联数组,通过给getInstance方法传入不同的参数获取不同的"单例对象"(引号的含义是:严格来说类可能被new多次,但是这个new也是在我们的控制之内的,而不是在类外部):

 代码如下 复制代码
class MysqlServer{
    //注意,变成复数了哦^_^  当然只是为了标识而已
    private static $instances = array();

    //业务变量,保持当前实例的mysqli对象
    private $conn;

    //显著特征:私有的构造方法,避免在类外部被实例化
    private function __construct($host, $username, $password, $dbname, $port){
        $this->conn = new mysqli($host, $username, $password, $dbname, $port);
    }

    //类唯一实例的全局访问点
    public static function getInstance($host='localhost', $username='root', $password='123456', $dbname='mydb', $port='3306'){
        $key = "{$host}:{$port}:{$username}:{$dbname}";
        if (empty(self::$instances[$key])){
            //这里也可以用 new self(); 的方式
            $class = __CLASS__;
            self::$instances[$key] = new $class($host, $username, $password, $dbname, $port);
        }
        return self::$instances[$key];
    }

    //重载__clone方法,不允许对象实例被克隆
    public function __clone(){
        throw new Exception("Singleton Class Can Not Be Cloned");
    }

    //查询业务方法,后面省略其它业务方法
    public function query($sql){
        return $this->conn->query($sql);
    }

    //尽早释放资源
    public function __destruct(){
        $this->conn->close();
    }
}

问题1:单例类能否拥有子类,因为单例类的构造方法是私有的,因此无法被继承,如果要继承则需要将构造方法改为protected或public,这就违背了单例模式的本意。因此,如果你想给单例类加子类,那就需要回头想想是否错用了模式,或者结构设计上有问题。

问题2:单例滥用,单例模式相对来说比较好理解和实现,因此一旦认识到单例模式的好处,很可能什么类都想写成单例,因此在使用次模式之前一定要考虑上述3种情况,看是否真的有必要使用。

今天在个数据库类时一直都没法获取最后保存数据的ID了,经过反复排查还是没找到原因,不过后来总结了一些查找出mysql指定表中最后一条记录的ID或直接是说最新插入记录的ID,下面一起来看看。

开发什么的最喜欢了。写程序可以提高实力又可以收藏一些代码!的确很是不错。由于某些原因需要获取数据库最大的id值。所以出现了这段php 获取数据库最大的id代码了。这里面的max(id) 这里面的id 就是要获取最大的id了。如果是别的字段请填写为其他字段

方法一
 
$fh = mysql_query("select  MAX(id)  from log");
$c_echo = mysql_fetch_array($fh);
echo $c_echo;
 

方法二


<?php
//执行插入数据库的语句
//……
$getID=mysql_insert_id();//$getID即为最后一条记录的ID
 ?>

PHP 函数 mysql_insert_id() 是返回在最后一次执行了 INSERT 查询后,由 AUTO_INCREMENT 定义的字段的值。

方法三

msyql_query("select last_insert_id()");

last_insert_id() 是mysql 一个函数 也是 对当前链接起效
此用法 解决了 mysql_insert_id () 中遇到的 bigint 型问题

[!--infotagslink--]

相关文章

  • IntelliJ IDEA2021.1 配置大全(超详细教程)

    这篇文章主要介绍了IntelliJ IDEA2021.1 配置大全(超详细教程),需要的朋友可以参考下...2021-04-18
  • Windows VPN服务器配置图文教程 超详细版

    VPN可以虚拟出一个专用网络,让远处的计算机和你相当于处在同一个局域网中,而中间的数据也可以实现加密传输,用处很大,特别是在一些大公司,分公司处在不同的区域。...2016-01-27
  • Tomcat配置及如何在Eclipse中启动

    这篇文章主要介绍了Tomcat配置及如何在Eclipse中启动,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-04
  • Laravel4安装配置的方法

    如果我们需要安培Laravel4的话最php最低要求要在php5.3.7版本并且我们需要把mcrypt与openss这两个扩展开启才可以,具体步骤我们参考下文。 前面我们介绍我了 com...2016-11-25
  • 详解Maven profile配置管理及激活profile的几种方式

    这篇文章主要介绍了详解Maven profile配置管理及激活profile的几种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-26
  • IDEA如何添加配置文件到classpath中

    这篇文章主要介绍了IDEA如何添加配置文件到classpath中,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-19
  • 查找php配置文件php.ini所在路径的二种方法

    通常php.ini的位置在:复制代码 代码如下:/etc目录下或/usr/local/lib目录下。如果你还是找不到php.ini或者找到了php.ini修改后不生效(其实是没找对),请使用如下办法:1.新建php文件,写入如下代码复制代码 代码如下:<?phpe...2014-05-31
  • 部署PHP时的4个配置修改说明

    以下就是部署PHP时的4个配置修改说明,大家一个一个进行学习研究。1、short_open_tag 是什么呢? 决定是否允许使用代码开始标志的缩写形式(<&#63; &#63;> )。如果要和 XML 结合使用PHP,可以禁用此选项以便于嵌入使用<&#63;x...2015-10-21
  • Vue-Router的routes配置详解

    在使用vue-router的项目中,实例化VueRouter是其配置选项routes该选项指定路由与视图的组件的关系或者路由与其他路由的关系,Router配置选项中是其中最重要的配置。本文就详细的介绍一下...2021-10-25
  • 华为畅享20Pro配置怎么样?华为畅享20Pro参数配置分析

    华为畅享20Pro配置怎么样?对于即将上市的华为畅享20 Pro手机,很多的网友们也是相当关注的,大家都想要知道这款华为畅享20 Pro手机的配置到底怎么样,赶紧看看吧...2020-06-29
  • 详解element-ui 表单校验 Rules 配置 常用黑科技

    这篇文章主要介绍了element-ui 表单校验 Rules 配置 常用黑科技,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-07-11
  • tomcat9 下载安装和配置+整合到eclipse的教程详解

    这篇文章主要介绍了tomcat9 下载安装和配置+整合到eclipse,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-07-28
  • pytest配置文件pytest.ini的详细使用

    这篇文章主要介绍了pytest配置文件pytest.ini的详细使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-17
  • 小记一次mysql主从配置解决方案

      今天研究了个开源项目,数据库是mysql的,其中的脚本数据需要备份,由于本人的机器时mac pro,而且mac下的数据库连接工具都不怎么好用,就想着如何利用windows下的数据库连接工具使用,并做相关备份,另外windows系统下的sqlyo...2015-10-21
  • vue配置多代理服务接口地址操作

    这篇文章主要介绍了vue配置多代理服务接口地址操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-08
  • apache中配置整合tomcat环境与安全配置

    系统:centos 5.9 环境:apache 2.2.25 tomcat 7.0.42 jdk 1.7.0 1.安装apache 我这里是直接yum安装的,如果你们要编译安装也不是不行. 代码如下 ...2016-01-28
  • mysql(master/slave)主从复制原理及配置图文详解

    这篇文章主要介绍了mysql(masterslave)主从复制原理及配置图文详解,以前脚本之家小编发过相关的内容,但这么好的非常少见特分享一下,需要的朋友可以参考下...2016-06-12
  • 手机配置那么高为什么玩王者荣耀还会卡?

    明明我的手机配置那么高(都八核了)为什么玩游戏还会卡?对安卓手机来说玩游戏卡顿的原因一般有两种;性能不足导致的卡顿以及CPU发热降频导致的卡顿,详情我们来看看吧...2017-07-06
  • 关于springboot中nacos动态路由的配置

    这篇文章主要介绍了springboot中nacos动态路由的配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-11
  • 配置vue全局方法的两种方式实例

    vue项目中有一些方法需要在多个页面调用,但为了避免在每个页面都import进来,可以把方法加到原型上去,这样在每个组件中都能使用了,下面这篇文章主要给大家介绍了关于配置vue全局方法的两种方式,需要的朋友可以参考下...2021-09-13