但是在具体生成id的时候,我们的操作顺序一般是:先在主表中插入记录,然后获得自动生成的id,以它为基础插入从表的记录。这里面有个困 难,就是插入主表记录后,如何获得它对应的id。 通常的做法,是通过“select max(id) from tablename”的做法,但是显然这种做法需要考虑并发的情况,需要在事务中对主表加以“X锁“,待获得max(id)的值以后,再解锁。 下面通过实验说明: 1、在连接1中向A表插入一条记录,A表包含一个auto_increment类型的字段。 2、在连接2中向A表再插入一条记录。 使用SCOPE_IDENTITY()可以 获得插入某个IDENTITY字段的当前会话的值,而使用IDENT_CURRENT()会获得在某个IDENTITY字段上插入的最大值,而不区分不同 的会话。 注:使用select last_insert_id()时要注意,当一次插入多条记录时,只是获得第一次插入的id值,务必注意!
稳定版可以从 GitHub Releases 获取。 开发版可以从 开发分支 获取。 安装 CodeIgniter4 可以手动安装,或使用 Composer 安装。 为了最大程度地保证安全性,系统目录以及任何应用程序的目录都在网站根目录之上,这样就无法通过浏览器直接访问到它们。 默认情况下,每一个目录下都包含有 .htaccess 文件来防止直接访问,但因为服务器配置改变或服务器不支持 .htaccess ,因此最好还是将它们从公共访问目录中移除。 如果你这样做,记住最好打开你的主 index.php 文件并将 $system_path,$application_folder 和 $view_folder 变量设置为全路径,例如:/www/MyUser 在生产环境中所要做的一个额外操作是禁用 PHP 错误报告以及其它任何仅开发时所使用的功能。在 CodeIgniter 中,可以通过设置 ENVIRONMENT 常量来完成。
一键领取预热专享618元代金券,2核2G云服务器爆品秒杀低至18元!云产品首单低0.8折起,企业用户购买域名1元起…
讲解 本教程旨在向您介绍CodeIgniter框架和MVC体系结构的基本原理。它将向您展示如何以逐步的方式构造基本的CodeIgniter应用程序。 在本教程中,您将创建一个基本的新闻应用程序。 您将从编写可加载静态页面的代码开始。接下来,您将创建一个新闻部分,该部分将从数据库中读取新闻项。最后,您将添加一个表单以在数据库中创建新闻项。 静态页面的模板目录为:application/Views/Pages/。 在该目录中,新建 Home.php 和 About.php 模板文件。在每个文件中任意输入一些文本然后保存它们。 最后要做的就是按顺序加载所需的视图,view() 方法中的参数代表要展示的视图文件名称。$data 数组中的每一个元素将被赋值给一个变量,这个变量的名字就是数组的键值。 每个规则都是一个正则表达式(左侧)映射到一个控制器和方法(右侧)。当获取到请求时,CodeIgniter 首先查找能匹配到的第一条规则,然后调用相应的可能存在参数的控制器和方法。
比如有一个CRM系统,需要用户输入上报公司信息之后,通过API接口返回提示信息。 ? 代码比较简单,知识将 request 的 input 内容复制给 Company 模型的属性,然后调用 save 方法将数据存入。 那么,如果想要获取存入后数据条目的ID,如何返回呢? 其实,save 方法本身就是链式调用的,会返回当前的 Company 模型对象。 ,返回的是当前写入的条目的ID。 但是,如果是并发的系统,或者在流程处理中,没有使用 Company 模型进行数据操作,而是 DB::statement,DB::insert 这些,获取到的,可就不是最后的ID了。
row in rows: print(row) # 查询第一条数据 row = handler.find_one() print(row) 其中,find()方法返回的是一个游标对象,我们可以直接对这个对象进行迭代 ,从而按顺序获取每一条数据。 需要注意,对游标对象执行了sort()方法以后,返回的依然是游标对象。所以如果我们只想获取最后一条数据怎么办呢? 这是由于游标对象是一个可迭代对象,所以可以使用next函数获取它第一次迭代的值。 我们平时使用find_one()时,返回的都是第一个满足条件的数据,那么有办法返回最后一个满足条件的数据呢? 如果列表里面有多个元组,那么先按第一个元组对应的字段排序,第一次排序的结果里面,值相同的再按第二个元组对应的字段排序,以此类推。
User::get(1); //获取主键为1的数据,得到的是一个对象 $res = $res- toArray(); //将对象转化为数组 dump($res- name); //获取 $res ,不报错,不写则默认为false;;;true 也可以换成一个数组,数组里存放数据表中的字段,表示仅允许数组中的字段添加数据 $res- id; //本次添加的自增id dump($res); $usermodel max('num'); //id<5 的记录中的 num 最大值 6、使用模型获取器 //model //方法名: get字段名Attr //controller中获取原始数据使用 $res- getData // database.php 中更改配置 'auto_timeStamp' = true // 不推荐使用此方法,因为如果你的数据库表中没有 对应的字段 ,程序可能就会报错 // 可以单独在 某个模型中 的记录 $res = User::withTrashed(true)- find(1); //得到id为1 的经过软删除 删除的记录 dump($res- getData()); //获取原始数据
用在公众的项目,最好还是按框架规范来,所以还是总结一下,免得以后别人再接手的时候贻笑大方。 1. 如果你之前没有使用过这种模式写过程序,你也许会皱起额头,不过你应该给自己尝试这样做的机会。 一条实践准则是把更少的东西放进 Controller ,记住 DRY 准则:不要重复造轮子。 安全问题很重要 在接收任何数据到你的程序之前,不管是表单提交的 POST 数据、COOKIE 数据、URI 数据、XML-RPC 数据、还是 SERVER 数组中的数据,我们都推荐你实践下面的三个步骤: ,记录日志的log_message,和引入错误页面的show_404是几个重要的函数;Compat主要解决了php4和php5中的函数不兼容问题,而constants则定义了一些读写文件权限的常量。 紧接着codeigniter载入了第一个类库,Benchmark,这个类库最简单的一个应用就是计算网页从开始到编译结束所花掉的时间,所以您在编译开始的地方打上一个标记,渲染结束后再打上一个标记,就可以算出其中花费的时间了
这与Services文件中的方法名称始终返回该类的SHARED实例相同,因此多次调用该函数应始终返回同一实例: $logger = service('logger'); 如果创建方法需要其他参数,则可以在服务名称之后传递它们 getSharedInstance()从工厂方法内部调用的方法很容易处理。这用于检查实例是否已在类中创建并保存,如果没有,则创建一个新实例。所有工厂方法都提供一个 值作为最后一个参数。 return self::getSharedInstance('routes'); } } 服务发现 CodeIgniter可以自动发现您可能在任何定义的名称空间中创建的任何ConfigServices.php 想象一下,您已经Blog在根目录中创建了一个新目录。这将包含一个带有控制器,模型等的Blog模块,并且您想将某些类作为服务使用。 当您想从任何控制器获取职位服务时,只需使用框架的Config\Services类即可获取服务: $postManager = Config\Services::postManager(); 注解 如果多个
当浏览器请求页面时,它会询问服务器是否可以获取该页面。然后, 服务器准备页面并将响应发送回发送请求的浏览器。就是这样简单,也可以说复杂些,但基本就是这样。 HTTP 是用于描述该交换约定的术语。 HTTP 请求 当客户端(浏览器,手机软件等)尝试发送 HTTP 请求时,客户端会向服务器发出一条文本消息然后等待响应。 Wikipedia 上有一篇文章,列出了 所有的请求头字段 (译者注:国内用户如果无法访问的话, 可以查看 在MDN上的页面 )。 HTTP 响应 服务器收到请求后,你的 web 应用程序会处理这条信息然后输出一些响应结果。服务器会将你的响应结果打包为对 客户端的的你的响应结果打包为对客户端的响应的一部分。 在 IANA 可以找到 完整的响应状态码列表 。
来自CodeIgniter中国的介绍 CodeIgniter 是一个轻量级、快速、灵活和安全的PHP全栈Web框架。 个人阅读笔记,仅作参考,若有错误后续改正 简要说明 入口文件index.php进行一些初始化动作 调用框架引导文件System\bootstrap.php预定义常量及加载相关类库,然后对CodeIgniter .php 根据CI_DEBUG标志来加载调试类库Kint 返回CI类 执行主流程 - CI->run() 开始基准测试 获取CodeIgniter\HTTP\Request对象 获取CodeIgniter 检测SPARKED标志,未定义则传入Response到after过滤器处理,获取返回的Response 存储当前URI信息,然后移除$uri $_SESSION['_ci_previous_url 检测SPARKED标志,未定义则传入Response到after过滤器处理,获取返回的Response 存储当前URI信息,然后移除$uri $_SESSION['_ci_previous_url
,并且必须在第一个参数中指定错误的”级别”,来表明这个信息的类型(debug,error等)。 配置文件中的 threshold (报错阈值)决定了从哪个级别开始的事件将会在整个应用中记录下来。如果应用中有任何低于报错阈值的事件记录被记录时,这些请求将会被忽略。 最为简单的使用阈值的方法就是将其设为你希望记录的报错等级的最低值。举例来说,如果你想记录warning信息,而不是information信息,就需要将报错阈值设为 5 。 这些内容将会插入到记录信息字符串中: // 生成一条例如这样的信息:用户123登录系统,登录IP为127.0.0.1 $info = [ 'id' => $user->id, 这样一来这个异常或错误对象包含的错误信息,文件名和对应行号就会生成一条字符串。 你需要在记录信息中中提供exception通配符: try { ...
1 <概述> 1.1 <目的> <读取 WinCC 在线表格控件中特定数据列的最大值、最小值和时间戳,并在外部对 象中显示。如图 1 所示。 左侧在线表格控件中显示项目中归档变量的值,右侧静态 文本中显示的是表格控件中温度的最大值、最小值和相应的时间戳。 1.2 <前提条件> <使用的软件版本为:WinCC V7.5 SP1。 项目中已经组态了变量记录。> 2 <组态步骤> <1. 创建两个文本变量 8 位字符集类型的变量 “startTime”和“endTime”,用于设定在 线表格控件的开始时间和结束时间。 如果不需要此功能,可以删除。 3 <操作说明> <1. 项目激活后,设置查询时间范围。如图 10 所示。 2. 点击 “执行统计” 获取统计的结果。如图 11 所示。 3.最后点击 “读取数据” 按钮,获取最大值、最小值和时间戳。如图 12 所示。
接下来你会看到如何创建一个简单的控制器,打开你的文本编辑器,新建一个文件 Blog.php , 然后放入以下代码: <? /index.php/blog/utility/ 将控制器放入子目录中 如果你正在构建一个比较大的应用,那么将控制器放到子目录下进行组织可能会方便一点。 CodeIgniter 也可以实现这一点。 你只需要简单的在 application/controllers/ 目录下创建新的目录,并将控制器文件放到子目录下。 你可以通过 $this->request 这个用法获取 POST 数据。 Validation Library docs 是有关规则和消息数组的格式以及可用规则的详细信息。 你可以在任何地方处理,你会发现控制器中的一些情况比模型简单,反之亦然。 就这样了! OK,总的来说,这就是关于控制器的所有内容了。
但是“MySQL服务端恶意读取客户端文件漏洞”在PHP7.3版本的Mysqli链接操作中被刻意注意到了这一点。所以该漏洞只能在PHP7.2.x版本中进行利用。 POC如下: <? 二、SQL注入 我们可以通过任意文件读取漏洞读取出数据库账号密码,然后再进行SQL注入。 ? 生成Payload后发送: ? CI框架的SQL注入处于WHERE条件,ThinkPHP3.2.3的SQL注入处于表名。 CI框架没有DEBUG模式,很难进行报错注入,而ThinkPHP存在DEBUG模式,可以进行报错注入。 但CNVD那里今天笔者突然得到了验证失败的“驳回”。 如图: ? 随后笔者去录制验证视频时,发现漏洞被“修补”? 我们通过CI框架的官网看到,是适用于PHP7.2.*版本的,如图: ? 可是为什么提交给该厂商之前PHP7.2.可以运行,而厂商驳回后,PHP7.2.则无法运行了?相信大家心中也已经有了答案。 通过github的最后修改日期我们可以看到该厂商私自修复漏洞的日期。 ?
==新版变化== 命名规范 目录和文件名采用‘小写+下划线’,并且以小写字母开头; 类库、函数文件统一以.php为后缀; 类的文件名均以命名空间定义,并且命名空间的路径和类库文件所在路径一致(包括大小写 b、无论require的位置如何,制定文件都将包含到出现require的脚本中。例如,即使require放在计算结果为假的if语句中,依然会包含指定文件。 介绍下GET和POST? 答: 1. get是从服务器上获取数据,post是向服务器传送数据。 2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。 建议: 1、get方式的安全性较Post方式要差些,包含机密信息的话,建议用Post数据提交方式; 2、在做数据查询时,建议用Get方式;而在做数据添加、修改或删除时,建议用Post方式; 如何获取指定网址里的 类型的方法或属性 ==private: 私有类型:== 该类型的属性或方法只能在该类中使用,在该类的实例、子类中、子类的实例中都不能调用私有类型的属性和方法 写出获取当前时间戳的函数,及打印前一天的时间的方法
CodeIgniter URL 在默认情况下,CodeIgniter 中的 URL 被设计成对搜索引擎和用户友好的样式。 -视图-控制器模式,那么 URI 中的每一段通常表示下面的含义: example.com/class/method/ID 第一段表示要调用的控制器 类 ; 第二段表示要调用的类中的 函数 或 方法 ; 第三段以及后面的段代表传给控制器的参数,如 ID 或其他任何变量; URI 类 和 URL 辅助函数 包含了一些函数可以让你更容易的处理 URI 数据。 在不同的服务器中,处理方式各异,故而如下我们主要展示两个最为通用的Web服务器。 Apache服务器 Apache需要开启 mod_rewrite 扩展。 NGINX 在NGINX中,我们可以定义一个 location 块并用 try_files 导向来取得如上文中 Apache 配置一样的效果: location / { try_files $uri
尽管 CodeIgniter 已经相当高效了,但是网页中的动态内容、主机的内存 CPU 和数据库读取速度等因素直接影响了网页的加载速度。 当页面第一次加载时,缓存将被写入到 application/cache 目录下的文件中去。 之后请求这个页面时,就可以直接从缓存文件中读取内容并输出到用户的浏览器。 开启缓存 将下面的代码放到任何一个控制器的方法内,你就可以开启缓存了: $this- output- cache($n); //其中 $n 是缓存更新的时间(单位分钟) 上面的代码可以放在方法的任何位置 如果你修改了可能影响页面输出的配置,你需要手工删除掉 你的缓存文件。 在写入缓存文件之前,你需要把 application/cache/ 目录的权限 设置为可写。 删除缓存 如果你不再需要缓存某个页面,你可以删除掉该页面上的缓存代码, 这样它在过期之后就不会刷新了。 注: 删除缓存代码之后并不是立即生效,必须等到缓存过期才会生效。
在模型中进行数据集查询,全部返回数据集对象,但使用的是think\model\Collection类,但用法是一致的。 可以直接使用数组的方式操作数据集对象,例如: // 获取数据集 $users = Db::name('user')- select(); // 直接操作第一个元素 $item = $users[0]; // 获取数据集记录数 $count = count($users); // 遍历数据集 foreach($users as $user){ echo $user['name']; echo $ ')- fetchCollection()- select(); // 直接操作第一个元素 $item = $users[0]; // 获取数据集记录数 $count = count($users); intersect 比较数组,返回交集 keys 返回数据中的所有键名 pop 删除数据中的最后一个元素 shift 删除数据中的第一个元素 unshift 在数据开头插入一个元素 reduce 通过使用用户自定义函数
接下来我们将介绍 如何在 application/libraries 目录下创建你自己的类库,和全局的框架类库独立开来。 另外,如果你希望在现有的类库中添加某些额外功能,CodeIgniter 允许你扩展原生的类, 或者你甚至可以在你的 application/libraries 目录下放置一个和原生的类库同名的文件 完全替代它 在你的 控制器 的任何方法中使用如下代码初始化你的类: $this- load- library('someclass'); 其中,someclass 为文件名,不包括 .php 文件扩展名。 既然类库是一个类,那么我们最好充分的使用 OOP 原则,所以,为了让类中的所有方法都能使用 CodeIgniter 超级对象,建议将其赋值给一个属性: class Example_library { 扩展原生类库 如果你只是想往现有的类库中添加一些功能,例如增加一两个方法, 这时替换整个类感觉就有点杀鸡用牛刀了。在这种情况下,最好的方法是 扩展类库。
扫码关注云+社区
领取腾讯云代金券