1144
主要的思想是利用call_user_func_array()和容器结合使用的。核心代码,理解都在注释中:1234567891011121314151617181920212223242526272829303132333435363738394041<?php//reqeuestFacade.php namespace facade{ class Request extends Facade{ public function getFacadeName(){ return 'request'; } } } ?> <?php//facade.phpnamespace facade{ class Facade{ public static function createFacade(){ $class = static::class; //在这个获取的$class其实是facade\reqeust //在这里利用static::得到getFacadeName,返回真正的request的变量名 $facadeClass = static::getFacadeName(); if ($facadeClass) { $class = $facadeClass; } elseif (isset(self::$bind[$class])) { $class = self::$bind[$class]; } //echo $class; 利用容器去获取reqeust,而不是facade\reqeust return \Container::get($class); } public static function __callStatic($method, $params) { return call_user_func_array([static::createFacade(), $method], $params); } }} ?>下面测试代码reqeust.php123456789101112<?php class Request{ public $name = 'Real Request'; public function sayName(){ echo $this->name; } } ?>test.php123456789101112<?php use facade\Request; include "Container.php"; include "Facade.php"; include "RequestFacade.php"; include "Request.php"; Request::sayName(); ?>推荐教程:thinkphp教程以上就是在thinkphp中实现facade的方法的详细内容
0
0 1396天前
997
ThinkPHP where()ThinkPHP where()方法是 Model 类内置方法,用于设置数据库查询或者更新、删除等操作条件。where 方法支持以字符串、数组和对象方式来设置条件,该方法不能独立使用,必须与 select()、find()、delete() 等数据操作方法搭配使用。字符串方式字符串方式条件即以字符串的方式将条件作为 where() 方法的参数,例子:12$Dao = M("User");$List = $Dao->where('uid<10 AND email="Jack@163.com"')->find();实际执行的 SQL 为:1SELECT * FROM user WHERE uid<10 AND email="Jack@163.com" LIMIT 1字符串方式设定的条件即为实际 SQL 执行的条件,也是最接近原生 SQL 的方式,ThinkPHP 不会对条件做任何(类型上的)检查。数组方式在大多数情况下推荐使用索引数组或者对象来作为查询条件,因为这样会更加安全,详细参见:《ThinkPHP 类型检测》。使用数组方式的 where 条件例子:12345$Dao = M("User");// 构建查询数组$condition['uid'] = array('elt',10);$condition['email'] = "Jack@163.com";$List = $Dao->where($condition)->find();这个例子跟上面使用字符串方式的例子执行效果是一样的。使用对象where 方法也可以使用对象来设置查询或操作条件,可以使用任何对象。以 stdClass 内置对象为例:123456$Dao = M("User");// 定义查询条件$condition = new stdClass(); $condition->uid = array('elt',10);$condition->email = "Jack@163.com";$List = $Dao->where($condition)->find();使用对象方式和使用数组方式的条件效果是相同的,并且是可以互换的。推荐教程:thinkphp教程以上就是ThinkPHP where方法介绍的详细内容
0
0 1396天前
1136
在thinkphp里面我们如何跨模块调用?在开发过程中经常会在当前模块调用其他模块的方法,这个时候就涉及到跨模块调用,我们还可以了解到A和R两个快捷方法的使用。12$User = A("User"); // 实例化UserAction控制器对象$User->importUser(); // 调用User模块的importUser操作方法这里的A("User") 是一个快捷方法,和下面的代码等效:12import("@.Action.UserAction");$User = new UserAction();事实上,在这个例子里面还有比A方法更简单的调用方法,例如:1R("User","importUser"); // 远程调用UserAction控制器的importUser操作方法上面只是在当前项目中调用,如果你有需要在多个项目之间调用方法,一样可以完成:1234$User = A("User","App2"); // 实例化App2项目的UserAction控制器对象$User->importUser(); // 远程调用App2项目的UserAction控制器的importUser操作方法R("User","importUser","App2");我的一个例子:一个项目下面分了两个组:admin和homehome默认是组:实例化模块的时候(当前位置是在admin中IndexAction类的index方法中实例化)1234import("@.Action.Home.UserAction");$User=new UserAction();$User->show();$User->add();注:调用的方法必须是 public型的推荐教程:thinkphp教程以上就是thinkphp跨模块调用方法的详细内容
0
0 1396天前
1035
phpMailer 是一个非常强大的 ph p发送邮件类,可以设定发送邮件地址、回复地址、邮件主题、html网页,上传附件,并且使用起来非常方便。Thinkphp3.2 PHPMailer 发送邮件结合QQ企业邮箱发送邮件下载附件PHPMailer解压到ThinkPHP\Library\Vendor在Common文件夹新建function.php1234567891011121314151617181920212223/** * 邮件发送函数 */ function sendMail($to, $title, $content) { Vendor('PHPMailer.PHPMailerAutoload'); $mail = new PHPMailer(); //实例化 $mail->IsSMTP(); // 启用SMTP $mail->Host=C('MAIL_HOST'); //smtp服务器的名称(这里以QQ邮箱为例) $mail->SMTPAuth = C('MAIL_SMTPAUTH'); //启用smtp认证 $mail->Username = C('MAIL_USERNAME'); //你的邮箱名 $mail->Password = C('MAIL_PASSWORD') ; //邮箱密码 $mail->From = C('MAIL_FROM'); //发件人地址(也就是你的邮箱地址) $mail->FromName = C('MAIL_FROMNAME'); //发件人姓名 $mail->AddAddress($to,"尊敬的客户"); $mail->WordWrap = 50; //设置每行字符长度 $mail->IsHTML(C('MAIL_ISHTML')); // 是否HTML格式邮件 $mail->CharSet=C('MAIL_CHARSET'); //设置邮件编码 $mail->Subject =$title; //邮件主题 $mail->Body = $content; //邮件内容 $mail->AltBody = "这是一个纯文本的身体在非营利的HTML电子邮件客户端"; //邮件正文不支持HTML的备用显示 return($mail->Send()); }添加配置文件config.php123456789// 配置邮件发送服务器 'MAIL_HOST' =>'smtp.exmail.qq.com',//smtp服务器的名称 'MAIL_SMTPAUTH' =>TRUE, //启用smtp认证 'MAIL_USERNAME' =>'jufengjituan@gsjfjt.com',//你的邮箱名 'MAIL_FROM' =>'jufengjituan@gsjfjt.com',//发件人地址 'MAIL_FROMNAME'=>'聚丰集团',//发件人姓名 'MAIL_PASSWORD' =>'******',//邮箱密码 'MAIL_CHARSET' =>'utf-8',//设置邮件编码 'MAIL_ISHTML' =>TRUE, // 是否HTML格式邮件最后就是使用PHPMailer发送邮件123456<form action="__URL__/add" method="post" enctype="multipart/form-data"> 邮箱:<input type="text" id="mail" name="mail"/> 标题:<input type="text" id="title" name="title"/> 内容<input type="text" id="content" name="content"/> <input class="button" type="submit" value="发送" style="margin: 0 auto;display: block;"/> </form>123456public function add(){ if(SendMail($_POST['mail'],$_POST['title'],$_POST['content'])) $this->success('发送成功!'); else $this->error('发送失败');}PHPMailer下载地址:https://github.com/PHPMailer/PHPMailer推荐教程:thinkphp教程以上就是ThinkPHP利用PHPMailer发送邮件的详细内容
0
0 1396天前
1022
1147
在 ThinkPHP 3.0 中引入了扩展配置。扩展配置的优先级仅次于动态配置而高于惯例配置,项目配置等。项目配置文件在部署模式的时候会纳入编译缓存,也就是说编译后再修改项目配置文件就不会立刻生效,需要删除编译缓存后才能生效。扩展配置文件则不受此限制影响,即使在部署模式下面,修改配置后也可以实时生效。基于扩展配置的以上特性,通常扩展配置是为了某些特殊的需要,而从项目配置里面分离出来的一些配置信息,这样的目的是为了便于维护和管理。定义扩展配置扩展配置文件位于项目配置目录下(PS:这个比较重要),如 Conf/user.php,要启用扩展配置,首先需要在项目配置文件里面定义 LOAD_EXT_CONFIG 参数:123'LOAD_EXT_CONFIG'=>'user',// 还可以定义多个扩展配置文件'LOAD_EXT_CONFIG'=>'user,db',如上面的参数定义所示,扩展配置可以是一个或多个配置文件。编辑 Conf/user.php 文件,写入配置参数:123456<?phpreturn array( 'USER_TYPE' => 2, 'USER_AUTH_TYPE' => 1,);?>那么在操作方法里就可以通过 C 方法来读取扩展配置里的参数:1C('USER_TYPE')在项目配置文件中,也可以以二级配置方式加载加载扩展配置文件:1'LOAD_EXT_CONFIG'=>array('USER'=>'user','DB'=>'db'),那么同样的 user.php 扩展配置文件,要获取配置参数值的方式改变为:1C('USER.USER_TYPE')二级配置方式,可以避免大项目中参数冲突问。避免和系统内置配置文件发生冲突下面表格中列出的配置文件已经被 ThinkPHP 系统使用,在定义扩展配置文件时,请勿使用下面的文件名:推荐教程:thinkphp教程以上就是ThinkPHP扩展配置的详细内容
0
0 1396天前
1018
在开发中,如果一个新增或修改的表单,在后台完成数据库操作后我们设定的不是跳转到其他页面,还是返回本页面,这时点击浏览器的后退再提交或刷新页面,会导致form表单重复提交,即这条记录会被增加或修改两次。导致表单重复提交的原因是:第一次提交的表单会被缓存到内存中,直到页面下次提交或页面关闭或转向其他页面时才消失。在自调用返回时,内存中的数据依然在,这时页面中的判断提交的代码依然可以检测到提交的值,顾会产生重复提交的效果。可以用以下几个办法解决:方法1:最简单:页面提交后转到另一个页面而不是本页面,举个栗子,比如你的页面地址为1http://yourdomain.com/User/Index/login则该页面的表单action地址可以为另外的处理地址,如1<form action="{:U('User/Index/check_login')}" method="post">这样报错返回,或者用户点击回退按钮,还是会回到上一个地址,不过这种情况也不保险。还要搭配方法2,一起比较保险方法2:提交表单后提交按钮变灰/隐藏提交按钮这种方式一般是结合方法1来做的,通过JS来动态监听用户的点击动作,动态将按钮属性置成disabeld,即为灰色不可用。代码如下:HTML:12345<form action="{:U('User/Index/check_login')}" method="post"> <input type="text" name="username" value="" id="username" /> <input type="password" name="userpwd" id="userpwd" /> <input type="submit" name="login_btn" id="login_btn" value="登陆"/></form>JS:12345$().ready(function(){ $("#login_btn").on('click',function(){ $(this).attr('disabled',true); });});方法1+方法2 结合后,基本上90%以上的重复提交问题都能解决,但是大刘这里还是要说下第三种方法,即在服务端一劳永逸的解决这个问题方法3:使用隐藏随机TOKEN值的方法进行重复提交判断首先,在项目的functions.php中添加如下方法1234567891011121314151617181920//创建TOKENfunction createToken() { $code = chr(mt_rand(0xB0, 0xF7)) . chr(mt_rand(0xA1, 0xFE)) .chr(mt_rand(0xB0, 0xF7)) . chr(mt_rand(0xA1, 0xFE)) . chr(mt_rand(0xB0, 0xF7)) . chr(mt_rand(0xA1, 0xFE)); session('TOKEN', authcode($code));}//判断TOKENfunction checkToken($token) { if ($token == session('TOKEN')) { session('TOKEN', NULL); return TRUE; } else { return FALSE; }}/* 加密TOKEN */function authcode($str) { $key = "YOURKEY"; $str = substr(md5($str), 8, 10); return md5($key . $str);}在表单页面form中填入以下HTML代码HTML:1<input type="hidden" name="TOKEN" value="{:session('TOKEN')}" />在页面展示前调用creatToken()方法生成token,在相应控制器POST请求中 使用 checkToken() 进行判断是否重复提交1234567if(IS_POST){$post_token = I('post.TOKEN'); if(!checkToken($post_token)){ $this->error('请不要重复提交页面',U('User/Index/login')); }}基本上,这3个方法配合着使用,就能解决ThinkPHP开发中表单重复提交问题,当然,有同学说可以使用ThinkPHP的令牌环机制,这样其实就更简单了,TP会默认在表单中生成一个隐藏域,到时候判断这个隐藏域是否存在以及和session中的值是否想的即可,原理和方法3是一样的。推荐教程:thinkphp教程以上就是thinkphp防止重复提交表单的技巧的详细内容
0
0 1396天前
1090
1、去官网下载类库 “https://www.barcodebakery.com/en/download”,选择自己的版本下载推荐教程:thinkphp教程2、解压放到“E:\phpstudy\PHPTutorial\WWW\guahao\vendor\下”,其中class文件是所有的类文件,生成条形码就是调用文件夹里的类,font文件是字体,index.php是一个可选择条件生成条形码的功能,是主程序的入口,test_1D.php是给的生成条形码的例子,test_1D.html是对应的渲染条形码的页面3、我们可以直接使用官方给的例子(test_1D.php),复制到自己需要用的地方,然后根据自己的需求稍加改动即可,需要注意的是,加载第三方类库的路径需要改一下。生成条形码的php代码1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556<?phpnamespace app\index\controller;use think\Controller;/*** 条形码操作类*/class Barcode extends Controller{ public function createBarcode() { $class_dir = VENDOR_PATH.'barcode/class/'; // Including all required classes require_once($class_dir.'BCGFontFile.php'); require_once($class_dir.'BCGColor.php'); require_once($class_dir.'BCGDrawing.php'); require_once($class_dir.'BCGcode39.barcode.php'); // Loading Font // 注意font和class是同一级文件夹 $font = new \BCGFontFile(VENDOR_PATH.'barcode/font/Arial.ttf', 18);// The arguments are R, G, B for color. $color_black = new \BCGColor(0, 0, 0); $color_white = new \BCGColor(255, 255, 255); $drawException = null; try { $code = new \BCGcode39(); $code->setScale(2); // Resolution $code->setThickness(30); // Thickness $code->setForegroundColor($color_black); // Color of bars $code->setBackgroundColor($color_white); // Color of spaces $code->setFont($font); // Font (or 0) 0不显示文字 $text = isset($_GET['text']) ? $_GET['text'] : 'HELLO'; $code->parse($text); // Text } catch(Exception $exception) { $drawException = $exception; } /* Here is the list of the arguments 1 - Filename (empty : display on screen) 2 - Background color */ $drawing = new \BCGDrawing('', $color_white); if($drawException) { $drawing->drawException($drawException); } else { $drawing->setBarcode($code); $drawing->draw(); } // Header that says it is an image (remove it if you save the barcode to a file) header('Content-Type: image/png'); header('Content-Disposition: inline; filename="barcode.png"'); // Draw (or save) the image into PNG format. $drawing->finish(\BCGDrawing::IMG_FORMAT_PNG); } public function barcodedes() { return $this->fetch(); }}?>接受渲染条形码的Html代码1<img src="{:url('createBarcode')}">当然,src还可以携带参数,只需更改以下代码html代码1<img src="{:url('createBarcode',array('text'=>'123'))}">php代码把1$text = isset($_GET['text']) ? $_GET['text'] : 'HELLO';改成1$text = input('text'); //接收的参数4、如果想把条形码保存到本地,在实例化“BCGDrawing”的时候填写保存路径即可12345678910111213141516171819202122232425262728293031323334353637383940414243444546// 文件路径 $file_dir = 'uploads/barcode/'.date('Y-m-d'); if (!file_exists($file_dir)) { mkdir($file_dir,0755,true); } $imgUrl = $file_dir.'/'.time().'.png'; $class_dir = VENDOR_PATH.'barcode/class/'; // Including all required classes require_once($class_dir.'BCGFontFile.php'); require_once($class_dir.'BCGColor.php'); require_once($class_dir.'BCGDrawing.php'); require_once($class_dir.'BCGcode39.barcode.php'); // Loading Font // 注意font和class是同一级文件夹 $font = new \BCGFontFile(VENDOR_PATH.'barcode/font/Arial.ttf', 18); // Don't forget to sanitize user inputs // $text = isset($_GET['text']) ? $_GET['text'] : 'HELLO'; // The arguments are R, G, B for color. $color_black = new \BCGColor(0, 0, 0); $color_white = new \BCGColor(255, 255, 255); $drawException = null; try { $code = new \BCGcode39(); $code->setScale(2); // Resolution $code->setThickness(30); // Thickness $code->setForegroundColor($color_black); // Color of bars $code->setBackgroundColor($color_white); // Color of spaces $code->setFont($font); // Font (or 0) $text = input('text'); //接收的参数 $text = isset($text) ? $text :'无参数'; $code->parse($text); // Text } catch(Exception $exception) { $drawException = $exception; } /* Here is the list of the arguments 1 - Filename (empty : display on screen) 2 - Background color */ // 保存到本地 (路径,颜色)路径为空则表示显示到页面上 $drawing = new \BCGDrawing($imgUrl, $color_white); if($drawException) { $drawing->drawException($drawException); } else { $drawing->setBarcode($code); $drawing->draw(); } $drawing->finish(\BCGDrawing::IMG_FORMAT_PNG);5、生成条形码之后,怎么判定条形码是否能用呢?可以把条形码保存成图片到本地,打开官网“https://www.onlinebarcodereader.com/”,上传刚刚生成的条形码,如果解析出的参数跟你输入的一样,说明条形码可以用。以上就是thinkphp5 + barcode 生成条形码的方法的详细内容
0
0 1396天前
1016
类库是ThinkPHP的核心部分,而ThinkPHP又通过基类库的概念把所有系统类库都集中在一起管理。核心基类库包括完成框架的通用性开发而必须的基础类和常用工具类。thinkPHP运行流程从tp5/public/index.php入口文件进入,通过加载框架引导文件/tp5/thinkphp/start.php进行初始化常量,注册各种需要的机制,加载配置文件。准备完成后即可通过/tp5/thinkphp/library/think/App.php类run()方法执行。准备工作对框架进行修改,切忌修改核心代码。一般方法是在特定目录下进行修改,调用。ThinkPHP提供了需要引入其他修改的特定目录 tp5/extend;(当然也可以在入口文件重新定义EXTEND_PATH)来自定义修改目录。建议能不修改不要修改。示例具体需求:给thinkphp引入自定义的分页类Pagination.php。然后调用分页类进行业务代码的编写。方法1:利用命名空间自动加载类文件放置目录:tp5/extend/page/admin/Pagination.php根据目录,给类文件绑定命名空间(psr-4规则):123456<?php namespace page\admin; class pagination { ……………………………… }以上用通俗的话来说,就是自动加载扩展类库,需要使用命名空间,并且命名空间要和目录对应。根目录是extend目录下开始的目录名。调用1$page = new page\admin\pagination();或者12use page\admin\pagination;$page = new pagination();方法2:不利用命名空间如果类文件没有命名空间,则无法自动加载。必须使用Loader类进行手动加载123use \think\Loader;Loader::import('page.admin.pagination');$page = new pagination();推荐教程:thinkphp教程以上就是在thinkphp5中添加自己的类库的详细内容
0
0 1396天前
980
ThinkPHP作为PHP框架,是单一入口的,那么其原始的URL便不是那么友好,但ThinkPHP提供了各种机制来定制需要的URL格式,本文就来为大家介绍一下thinkphp中设置url格式的方法。ThinkPHP 作为 PHP 框架,是单一入口的,那么其原始的 URL 便不是那么友好。但 ThinkPHP 提供了各种机制来定制需要的 URL 格式,配合 Apache .htaccess 文件,更是可以定制出人性化的更利于 SEO 的 URL 地址来。.htaccess文件是 Apache 服务器中的一个配置文件,它负责相关目录下的网页配置。我们可以利用 .htaccess 文件的 Rewrite 规则来隐藏掉 ThinkPHP URL 中的 index.php 文件(即入口文件),这也是 ThinkPHP URL 伪静态的第一步。例如原来的 URL 为:1http://127.0.0.1/index.php/Index/insert去掉 index.php 之后变为:1http://127.0.0.1/Index/insert如此一来,就变成了 http://服务器地址/应用模块名称/操作名称[/变量参数] 的常见 URL 格式。更改 Apache httpd.conf 配置文件提示:如果在虚拟主机商配置,请直接配置第三、四步,因为支持 .htaccess 的空间已经配置好了前面两步。用编辑器打开 Apache 配置文件 httpd.conf(该文件位于 Apache 安装目录Apache2conf),并按如下步骤修改。一、加载了 mod_rewrite.so确认加载了 mod_rewrite.so 模块(将如下配置前的 # 号去掉):1LoadModule rewrite_module modules/mod_rewrite.so二、更改 AllowOverride 配置更改需要读取 .htaccess 文件的目录,将原来的目录注释掉:12#<Directory "C:/Program Files/Apache Group/Apache2/htdocs"><Directory E:/html/myapp>更改 AllowOverride None 为 AllowOverride FileInfo Options ,更改后的配置如下所示:1234#<Directory "C:/Program Files/Apache Group/Apache2/htdocs"><Directory E:/html/myapp> AllowOverride FileInfo Options</Directory>.htaccess 是基于目录来控制的,<Directory E:/html/myapp> 该句即表示需要读取 .htaccess 文件的目录,要根据实际具体 Apache 的解析目录来配置。虚拟主机如果提供 .htaccess 控制,一般都已经配置好了。三、添加 .htaccess 文件 Rewrite 规则在需要隐藏 index.php 的目录下(本教程中为 E:/html/myapp,也即入口文件所在目录)创建 .htaccess 文件,并写入如下规则代码:12345678910<IfModule mod_rewrite.c>RewriteEngine on #不显示index.php RewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME} !-fRewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] </IfModule>四、更改项目配置文件编辑项目配置文件 Conf/config.php ,将 URL 模式配置为 2(Rewrite模式):1'URL_MODEL'=>2,至此,各个配置已经完成。保存各配置文件后,重启 Apache 服务器并删除 Runtime 目录下的项目缓存文件,在浏览器访问隐藏 index.php 后的地址测试是否成功:1http://127.0.0.1/html/myapp/Index/index如果访问成功,那么利用 Apache .htaccess 文件的 Rewrite 规则隐藏 index.php 入口文件的配置就成功了。推荐教程:thinkphp教程以上就是thinkphp中设置伪静态的方法的详细内容
0
0 1396天前
1106
在用thinkphp的时候,通常会直接访问IndexController控制下面的Index方法.那它是通过什么设置的呢?ThinkPHP根目录设置在根目录下面的ThinkPHP/conf/convention.php找到123'DEFAULT_MODULE' => 'Home', // 默认模块'DEFAULT_CONTROLLER' => 'Index', // 默认控制器名称'DEFAULT_ACTION' => 'index', // 默认操作名称这三个的意思就是Home模块下面的Index控制器下面的index方法。配置文件设置在Common/conf/config.php中添加一段例如我想要访问Aplication下面的App控制下面的login方法123'DEFAULT_MODULE' => 'Aplication', // 默认模块'DEFAULT_CONTROLLER' => 'App', // 默认控制器名称'DEFAULT_ACTION' => 'login', // 默认操作名称同上面一样,就可以生效了。推荐教程:thinkphp教程以上就是thinkphp设置默认访问路径的方法的详细内容
0
0 1396天前
980
在ThinkPHP中系统提供以下几个查询方法的使用,方便于在后期需要做统计的使用:count() 表示查询表中总的记录数max() 表示查询某个字段的最大值min() 表示查询某个字段的最小值avg() 表示查询某个字段的平均值sum() 表示求出某个字段的总和一、count方法语法:1$model -> [where() -> ] count();案例:查询部门表中的总记录数。12345678910//count方法public function test(){ //实例化模型 $model = M('Dept'); //count方法 $result = $model -> count(); //打印 dump($result); }显示结果:返回值是字符的形式。sql跟踪信息中的结果:数据库中的信息:二、max方法语法:1$model -> max('字段名');案例:查询部门表中id最大的部门。在以后开发的时候会有一个应用是通过max方法查询最后注册会员的id。123456789//max方法public function test(){ //实例化模型 $model = M('Dept'); //max方法 $result = $model -> max('id'); //打印 dump($result);}显示结果:返回值是字符的形式。sql跟踪信息中的结果:数据库中的信息:三、min方法语法:1$model -> min('字段名')案例:查询部门表中id最小的部门。在以后开发的时候会有一个应用是通过min方法查询最早注册会员的id。123456789//min方法public function test(){ //实例化模型 $model = M('Dept'); //max方法 $result = $model -> min('id'); //打印 dump($result);}显示结果:返回值也是字符的形式。sql跟踪信息中的结果:数据库中的信息:四、avg方法语法:1$model -> avg('字段名');案例:求出部门表中id的平均值。123456789//avg方法public function test(){ //实例化模型 $model = M('Dept'); //max方法 $result = $model -> avg('id'); //打印 dump($result);}显示结果:返回值也是字符的形式。sql跟踪信息中的结果:数据库中的信息:五、sum方法语法:1$model -> sum('字段名');案例:查询字段id的总和。123456789//sum方法public function test(){ //实例化模型 $model = M('Dept'); //max方法 $result = $model -> sum('id'); //打印 dump($result);}显示结果:返回值同样是字符的形式。sql跟踪信息中的结果:数据库中的信息:推荐教程:thinkphp教程以上就是thinkphp中统计查询的方法介绍的详细内容
0
0 1396天前
1043
钩子是一种触发机制,如同一个陷阱,当程序运行到某个地方时就会触发这个陷阱,然后执行这个Hook,执行完成后,系统根据执行的不同结果继续进行。框架在\Think\Think->start()方法中调用Hook类中的import方法批量加载模式行为:默认为\Model\common.php中的配置文件,该文件定义行为扩展.2、通过Hook:listen()方法监听tag标记的行为.Hook类中定义一个数组tags:tag为key;Behavior行为是value.通过Hook:exec()执行该标记的行为插件。12345678910111213141516171819202122232425262728293031323334353637383940414243444546/** * 监听标签的插件 * @param string $tag 标签名称 * @param mixed $params 传入参数 * @return void */ static public function listen($tag, &$params=NULL) { if(isset(self::$tags[$tag])) { if(APP_DEBUG) { G($tag.'Start'); trace('[ '.$tag.' ] --START--','','INFO'); } foreach (self::$tags[$tag] as $name) { APP_DEBUG && G($name.'_start'); $result = self::exec($name, $tag,$params); if(APP_DEBUG){ G($name.'_end'); trace('Run '.$name.' [ RunTime:'.G($name.'_start',$name.'_end',6).'s ]','','INFO'); } if(false === $result) { // 如果返回false 则中断插件执行 return ; } } if(APP_DEBUG) { // 记录行为的执行日志 trace('[ '.$tag.' ] --END-- [ RunTime:'.G($tag.'Start',$tag.'End',6).'s ]','','INFO'); } } return; } /** * 执行某个插件 * @param string $name 插件名称 * @param string $tag 方法名(标签名) * @param Mixed $params 传入的参数 * @return void */ static public function exec($name, $tag,&$params=NULL) { if('Behavior' == substr($name,-8) ){ // 行为扩展必须用run入口方法 $tag = 'run'; } $addon = new $name(); return $addon->$tag($params); }推荐教程:thinkphp教程以上就是thinkphp钩子实现方法的详细内容
0
0 1396天前
852
1、方法一:v3.2.1①、ThinkPHP/Library/Behavior/CronRunBehavior.class.php文件在这里首先要说的就是这个自动执行任务文件,官方所给的这个文件存在BUG,我是用的是v3.2.1版本,后面的版本是否有改正大家可以尝试一下。12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152<?php/** * ======================================= * Created by WeiBang Technology. * Author: ZhiHua_W * Date: 2016/9/22 0005 * Time: 上午 11:12 * Project: ThinkPHP实现定时执行任务 * Power: 自动执行任务 * ======================================= */namespace Behavior; class CronRunBehavior{ public function run(&$params) { if (C('CRON_CONFIG_ON')) { $this->checkTime(); } } private function checkTime() { if (F('CRON_CONFIG')) { $crons = F('CRON_CONFIG'); } else if (C('CRON_CONFIG')) { $crons = C('CRON_CONFIG'); } if (!empty($crons) && is_array($crons)) { $update = false; $log = array(); foreach ($crons as $key => $cron) { if (empty($cron[2]) || $_SERVER['REQUEST_TIME'] > $cron[2]) { G('cronStart'); R($cron[0]); G('cronEnd'); $_useTime = G('cronStart', 'cronEnd', 6); $cron[2] = $_SERVER['REQUEST_TIME'] + $cron[1]; $crons[$key] = $cron; $log[] = 'Cron:' . $key . ' Runat ' . date('Y-m-d H:i:s') . ' Use ' . $_useTime . ' s ' . "\r\n"; $update = true; } } if ($update) { \Think\Log::write(implode('', $log)); F('CRON_CONFIG', $crons); } } }}②、tgs.php在Application/Common/Conf文件夹中新建tags.php文件,进行标签设置。123456<?php return array( //'配置项'=>'配置值' 'app_begin' =>array('Behavior\CronRunBehavior'),);③、config.php在Application/Common/Conf文件夹中的config.php文件进行自动运行配置。12345678<?phpreturn array( /* 自动运行配置 */ 'CRON_CONFIG_ON' => true, // 是否开启自动运行 'CRON_CONFIG' => array( '测试执行定时任务' => array('Home/Index/crons', '5', ''), //路径(格式同R)、间隔秒(0为一直运行)、指定一个开始时间 ),);④、IndexController.class.php在Application/Home/Controller/IndexController.class.php文件中进行定时执行任务的编写。123456789101112131415161718192021222324252627282930313233343536373839<?php/** * ======================================= * Created by WeiBang Technology. * Author: ZhiHua_W * Date: 2016/9/22 0005 * Time: 上午 11:20 * Project: ThinkPHP实现定时执行任务 * Power: 自动执行任务方法控制器 * ======================================= */namespace Home\Controller; use Think\Controller; class IndexController extends Controller{ /* public function index(){ $this->show('<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} body{ background: #fff; font-family: "微软雅黑"; color: #333;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.8em; font-size: 36px }</style><div style="padding: 24px 48px;"> <h1>:)</h1><p>欢迎使用 <b>ThinkPHP</b>!</p></div><script type="text/javascript" src="http://tajs.qq.com/stats?sId=9347272" charset="UTF-8"></script>','utf-8'); } */ public function index() { $contents = file_get_contents("test.txt"); //每次访问此路径将内容输出,查看内容的差别 var_dump($contents); exit; $this->assign("contents", $contents); $this->display(); } //定时执行的方法 public function crons() { //在文件中写入内容 file_put_contents("test.txt", date("Y-m-d H:i:s") . "执行定时任务!" . "\r\n<br>", FILE_APPEND); }}这样定时执行任务我们就写好了,每隔5秒我们访问任何项目的url,然后查看根目录下的test.txt文件就会发现里面的内容变化。注意:当你修改间隔时间时会发现没有生效,这是你需要将Runtime/Data文件夹下的缓存文件删除,间隔时间缓存存放在CRON_CONFIG.php文件中。2、方法2:v3.2.2此方法和方法一没有多大的区别。①、tags.php在/Application/Common/Conf目录下新建tags.php文件。(此和方法一处一样)123456<?php return array( //'配置项'=>'配置值' 'app_begin' =>array('Behavior\CronRunBehavior'),);②、crons.php在/Application/Common/Conf目录下新建crons.php文件。(此处和方法一有区别,注意区分。)1234567<?php return array( //myplan为我们计划定时执行的方法文件,2是间隔时间,nextruntime下次执行时间 //此文件位于/Application/Cron/目录下 'cron' => array('myplan', 2, nextruntime),);③、myplan.php在/Application/Common/目录下新建 Cron文件夹,里面新建文件myplan.php文件。123<?php echo date("Y-m-d H:i:s")."执行定时任务!" . "\r\n<br>";此时我们就可以访问项目的url,然后我们会发现在Application/Runtime/目录下生成了~crons.php文件,文件内容如下:1234567891011<?php return array ( 'cron' => array ( 0 => 'myplan', 1 => 60, 2 => 1398160322, ), ); ?>推荐教程:thinkphp教程以上就是thinkphp设置定时执行任务的方法的详细内容
0
0 1396天前
1303
在我们使用ThinkPHP框架时可能会遇到无法加载控制器的问题:相信许多PHP开发者在使用ThinkPHP框架进行快速开发的时候遇到过通过URL访问控制器方法时遇到图上的这种问题。为什么会无法加载控制器呢,原因有很多,但是据我所了解的来看,最有可能的还是:你的Controller文件夹下没有存放你控制器的文件,因为很可能你在开始学习或者测试的时候将控制器类写在了Index控制器的文件中,但是在ThinkPHP中,在IndexController.class.php文件中写两个类是不规范的,因为两个类如果写在了同一个文件里,那么在通过URL访问文件名以外的其它类时,就像这样,http://localhost:81/thinkphp_3.2.3_core/index.php/Home/Blog/read/5,系统是找不到这个控制器的。也就是说,系统找到这个控制器只有通过文件名BlogController.class.php来找,你如果没有新建这个文件是不能指望系统帮你从IndexController.class.php这个文件找的,因为在Controller文件夹下如果找不到BlogController.class.php这个文件,系统就认为你没有写这个控制器,所以才会出现那样的错误。我原来以为是因为没有开启参数绑定功能,但是我找到ThinkPHP\Conf\convention.php看到这个第二行显示参数绑定功能是开启的,所以就否定了我原来的想法,后来通过咨询其他人才意识到是没有新建文件的原因。以上就是解决thinkphp中控制器无法加载的问题的详细内容
0
0 1396天前
1077
tp5.0去掉index.php的实现方法首先找到本地服务器中的WWW目录。进入www目录,找到tp5.0的框架,我这里命名的是tp5.0,当然也可以是其他名字,只要框架使用的是tp5.0就行。找到public文件。在public文件下找到.htaccess文件。然后选择打开方式。打开之后我们进入文件,找到RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1] 这一句话,这句话就是将index.php隐藏掉的,我们在访问地址栏的时候就可以省略掉index.php.如果我们不想省略掉这个index.php的话,我们就可以将这句话去掉。推荐教程:thinkphp教程以上就是tp5.0去掉index.php的实现方法的详细内容
0
0 1396天前
1176
这是在TP5使用链式方法查询数据库时遇到的问题:原因是每个链式方法都会返回一个Query对象,Query.php的370行中 $str {0} 这种写法被废弃了。改为 substr($value ,0,1) ,如下。错误消失:推荐相关教程:《TP5》以上就是关于TP5框架中Query.php中废弃写法的详细内容
0
0 1396天前
1076
tp_data 数据表value()123456789101112$name = Db::name('data') -> where('id', 16) -> value('name');print_r($name); // 获取 tp_data 数据表中 id = 16,name 字段的值,并打印// 结果:1111 /** 原生sql语句>Prepare SELECT `name` FROM `tp_data` WHERE `id` = ? LIMIT 1>Execute SELECT `name` FROM `tp_data` WHERE `id` = 16 LIMIT 1*/column()获取一列满足条件的数据12345678910111213141516171819$list = Db::name('data) -> where('status', 1) -> column('name');print_r($list); // 从 tp_data 数据表获取一列 status = 1 的 name 字段值/** 结果:Array( [0] => thinkphp [1] => thinkphp [2] => thinkphp [3] => thinkphp [4] => 7777777777 [5] => thinkphp [6] => thinkphp [7] => thinkphp [8] => thinkphp)*/获取一列满足条件的数据,并以id值为键名12345678910111213141516171819$list = Db::name('data) -> where('status', 1) -> column('name', 'id');print_r($list); // 从 tp_data 数据表获取一列 status=1 的 name 字段值集合/** 结果:Array( [3] => thinkphp [4] => thinkphp [5] => thinkphp [6] => thinkphp [7] => 7777777777 [8] => thinkphp [9] => thinkphp [10] => thinkphp [11] => thinkphp)*/获取以id为键名的数据集1234567891011121314151617181920212223242526$list = Db::name('data') -> where('status', 1) -> column('*', 'id');print_r($list); // 从 tp_data 数据表获取一列 status=1 的数据集/** 结果:Array( [3] => Array( [id] => 3 [name] => thinkphp [status] => 1 ) [4] => Array( [id] => 4 [name] => thinkphp [status] => 1 ) [5] => Array( [id] => 5 [name] => thinkphp [status] => 1 ) ...)*/聚合查询countmaxminavgsum统计 data 表的数据123456$count = Db::name('data') -> where('status', 1) -> count();echo $count; // 结果:9统计 data 表的最大 id12345$max = Db::name('data') -> where('status', 1) -> max('id);echo $max;// 结果:11简单查询1234567891011121314151617181920212223$result = Db::name('data') -> where("id > :id and name like :name", [ 'id' => 10, 'name' => "%php%" ]) -> select();print_r($result); /** 结果:Array( [0] => Array( [id] => 11 [name] => thinkphp [status] => 1 ))*/ /** 原生sql语句:>Prepare SELECT * FROM `tp_data` WHERE (id > ? and name like ?)>Execute SELECT * FROM `tp_data` WHERE (id > '10' and name like '%php%')*/日期查询日期类型int,时间戳格式查询时间大于 2016-1-1 的数据123456789$result = Db::name('users') -> whereTime('reg_time', '>', '2016-1-1') -> select();print_r($result); /** 原生sql语句:>Prepare SELECT * FROM `tp_users` WHERE `reg_time` > ?>Execute SELECT * FROM `tp_users` WHERE `reg_time` > 1451577600*/查询本周123456$result = Db::name('users') -> whereTime('reg_time', '>', 'this week') -> select();print_r($result); // 从本周星期一开始查询最近两天添加的数据1234$result = Db::name('users') -> whereTime('reg_time', '>', '-2 days') -> select();print_r($result);查询创建时间在 2016-1-1 ~ 2017-7-1 的数据123456789$result = Db::name('users') -> whereTime('reg_time', 'between', ['2016-1-1', '2017-7-1']) -> select();print_r($result); /** 原生sql语句:>Prepare SELECT * FROM `tp_users` WHERE `reg_time` BETWEEN ? AND ?>Execute SELECT * FROM `tp_users` WHERE `reg_time` BETWEEN 1451577600 AND 1483200000*/查询今天的数据昨天:yesterday本周:week上周:last week1234$result = Db::name('users') -> whereTime('reg_time', 'today') -> select();print_r($result);分块查询1234567891011121314151617181920212223242526Db::name('data') -> where('status', '>', 0) -> chunk(2, function($list) { foreach($list as $data) { //处理2条记录 } }); /** 原生sql语句:>Prepare SELECT * FROM `tp_data` WHERE `status` > ? ORDER BY `id` asc LIMIT 2>Execute SELECT * FROM `tp_data` WHERE `status` > 0 ORDER BY `id` asc LIMIT 2>Close stmt>Prepare SELECT * FROM `tp_data` WHERE `status` > ? AND `id` > ? ORDER BY `id` asc LIMIT 2>Execute SELECT * FROM `tp_data` WHERE `status` > 0 AND `id` > 4 ORDER BY `id` asc LIMIT 2>Close stmt>Prepare SELECT * FROM `tp_data` WHERE `status` > ? AND `id` > ? ORDER BY `id` asc LIMIT 2>Execute SELECT * FROM `tp_data` WHERE `status` > 0 AND `id` > 6 ORDER BY `id` asc LIMIT 2>Close stmt...>Prepare SELECT * FROM `tp_data` WHERE `status` > ? AND `id` > ? ORDER BY `id` asc LIMIT 2>Execute SELECT * FROM `tp_data` WHERE `status` > 0 AND `id` > 16 ORDER BY `id` asc LIMIT 2>Close stmt>Prepare SELECT * FROM `tp_data` WHERE `status` > ? AND `id` > ? ORDER BY `id` asc LIMIT 2>Execute SELECT * FROM `tp_data` WHERE `status` > 0 AND `id` > 17 ORDER BY `id` asc LIMIT 2>Close stmt*/改进123456$p = 0;do { $result = Db::name('data') -> limit($p, 2) -> select(); $p += 2; //处理数据} while(count($result) > 0);推荐教程:《TP5》以上就是thinkphp5中常用数据库查询语句介绍的详细内容
0
0 1396天前
927
ThinkPHP遵循惯例重于配置的原则,系统会按照下面的顺序来加载配置文件(配置的优先顺序从右到左)。惯例配置->应用配置->模块配置->动态配置惯例配置:核心框架内置的配置文件,无需更改。应用配置:每个应用的全局配置文件(框架安装后会生成初始的应用配置文件),有部分配置参数仅能在应用配置文件中设置。模块配置:每个模块的配置文件(相同的配置参数会覆盖应用配置),有部分配置参数模块配置是无效的,因为已经使用过。动态配置:主要是指在控制器或者行为中进行(动态)更改配置,该配置方式只在当次请求有效,因为不会保存到配置文件中。TP5.1的数据库配置文件在application\config\database.php中当然,在application\模块名\config\database.php(模块配置)中的配置,优先级会比在application\config\database.php(应用配置)中高比如同时在模块配置和在应用配置中配置数据库连接,那么会优先使用模块配置,如果模块配置中没有,那么会去找应用配置中的配置信息。动态配置的优先级最高。我们只需要在控制器和数据库配置文件中操作即可,无需用到模型123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687<?php// +----------------------------------------------------------------------// | ThinkPHP [ WE CAN DO IT JUST THINK ]// +----------------------------------------------------------------------// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.// +----------------------------------------------------------------------// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )// +----------------------------------------------------------------------// | Author: liu21st <liu21st@gmail.com>// +---------------------------------------------------------------------- return [ // 数据库类型 'type' => 'mysql', // 服务器地址 'hostname' => '127.0.0.1', // 数据库名 'database' => '', // 用户名 'username' => 'root', // 密码 'password' => '', // 端口 'hostport' => '', // 连接dsn 'dsn' => '', // 数据库连接参数 'params' => [], // 数据库编码默认采用utf8 'charset' => 'utf8', // 数据库表前缀 'prefix' => '', // 数据库调试模式 'debug' => true, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) 'deploy' => 0, // 数据库读写是否分离 主从式有效 'rw_separate' => false, // 读写分离后 主服务器数量 'master_num' => 1, // 指定从服务器序号 'slave_no' => '', // 自动读取主库数据 'read_master' => false, // 是否严格检查字段是否存在 'fields_strict' => true, // 数据集返回类型 'resultset_type' => 'array', // 自动写入时间戳字段 'auto_timestamp' => false, // 时间字段取出后的默认时间格式 'datetime_format' => 'Y-m-d H:i:s', // 是否需要进行SQL性能分析 'sql_explain' => false, // Builder类 'builder' => '', // Query类 'query' => '\\think\\db\\Query', // 是否需要断线重连 'break_reconnect' => false, // 断线标识字符串 'break_match_str' => [], 'db_config1' => [ // 数据库类型 'type' => 'sqlsrv', // 服务器地址 'hostname' => '192.168.1.1', // 用户名 'username' => 'username', // 密码 'password' => 'passwd', // 数据库名称 'database' => 'dbname', ], 'db_config2' => [ // 数据库类型 'type' => 'mysql', // 服务器地址 'hostname' => '192.168.1.2', // 用户名 'username' => 'username', // 密码 'password' => 'passwd', // 数据库名称 'database' => 'dbname', ]];db_config1和db_config2可以看作是两个不同的数据库连接我们在控制器中就可以这样调用不同的数据库1234567891011<?phpuse think\Db;$verify1 = Db::connect('db_config1')->table('tablename')->where([ ['username','=',$username], ['password','=',$password],])->find(); $verify2 = Db::connect('db_config2')->table('tablename')->where([ ['username','=',$username], ['password','=',$password],])->find();推荐教程:《TP5》以上就是thinkphp5多数据库配置介绍的详细内容
0
0 1396天前
989
html页面中,引用了bootstrap 的图标1234567891011{if condition="$color == 5"}<div > <!-- <i id="collection" class="icon-heart cs"></i><br /> --> <!-- <i id="collection" class="icon-heart" class2="cs"></i><br /> --> <i id="collection" class="icon-heart cs"></i><br /></div>{else/}<div > <i id="collection" class="icon-heart"></i><br /></div>{/if}css 样式1234<style>.like{ font-size:66px; color:#ccc; cursor:pointer;}.cs{color:#FF0000;}</style>js 中1234567891011121314151617181920212223242526272829$("#collection").click(function(){$.ajax({ type:'POST', url:"home_collection.html", data:{ "art_id": {$data['id']}, // 传过去文章表的id }, dataType:"json", success:function(data){ var res = JSON.parse(data); // json 字符串转化为对象 if (res.code == '3') // 收藏成功,变成红色 { $('#collection').toggleClass('cs'); // document.getElementById('collection').style.background="#FF0000"; // 另一种样式,这是把整个背景都变红了 console.log(res.code); } if (res.code == '4') // 取消收藏 { $('#collection').toggleClass('cs'); console.log(res.code); } }, error:function(data){ console.log(data); console.log(data.code); alert(222); } }); });控制器中123456789101112131415161718192021222324// 当图标变颜色的时候,点击是取消收藏,当图片没颜色的时候点击是收藏// 查询数据库是否存在,如果不存在则加入,存在则删除,前台也变样式public function collection(){$data = $_POST;$uname1 = session::get('USER_INFO');$uid = $uname1['uid'];// 应该查询当前用户对应的art_id 存不存在在 收藏表 中$result = DB::name('collection')->where('art_id',$data['art_id'])->select();if($result){$aa = DB::name('collection')->where('art_id',$data['art_id'])->delete();$returnData = ['code'=>4, 'info'=>'取消收藏'];}else{$bb['art_id'] = $data['art_id']; // 对应文章表的id$bb['uid'] = $uid ;$bb = DB::name('collection')->insert($bb);$returnData = ['code'=>3, 'info'=>'收藏成功'];}// header('Content-Type:application/json; charset=utf-8'); $data3 = json_encode($returnData,JSON_UNESCAPED_UNICODE); //这样也正确return $data3;// return json_encode($returnData);// 这样返回格式正确}推荐教程:《TP5》以上就是tp5实现收藏功能并且可切换颜色的方法的详细内容
0
0 1396天前