PHP_Smarty

模板

数据与表现层的标签分离

smarty是PHP 与 HTML代码的分离

小型模板类

$smarty 的工作流程:

  1. 把需要显示的全局变量,赋值塞到对象内部的属性上,一个数组中.

  2. 编译模板,把{$标签},解析成相应的<?php echo 代码

  3. 引入编译后的PHP文件

使用smarty的步骤:

  1. smarty是一个类,要使用,需要先引入并实例化

  2. assign赋值

  3. display --> 编译到输出

smarty缺点:

  1. 编译模板,需要消耗时间

  2. 要把变量再重新赋值一份(又倒腾一次,放在对象的属性上)

<?php/*** 小型模板类*//*** 1. 把标签解析成PHP输出语句* 2. 模板文件-->PHP文件*         区分 模板文件和 PHP文件,把模板和编译后的结果,放置在不同的目录中.*         用2个不同的属性来记录 不同的目录    */class Tmp {public $template_dir = ''; // 模版文件所在的路径public $compile_dir = ''; // 模板编译后存在的路径public $tpl_var = array(); // 接受外部的变量/*** 存储全局变量* @param {String} $key 变量名* @param {Mixin} $val 变量值 */public function assign( $key, $val ) {$this->tpl_var[$key] = $val;}/*** 调用 compile模板,和自动引入* @param {String} $template 模板文件名*/public function display( $template ) {$comp = $this->compile($template);include($comp);}/*** 编译* @param {String} $template 模板文件名 (需要编译的模板文件的文件名)* @return {String} $comp 编译后的文件路径 * * 把指定的模板内容读取,再编译成PHP文件* * 最终外部执行的是,编译后的文件*/public function compile( $template ) {// 读取模板内容$tmp = $this->template_dir . '/' . $template;$scoure = file_get_contents($tmp);    // 替换模板内容$scoure = str_replace('{$', '<?php echo $this->tpl_var[\'', $scoure);$scoure = str_replace('}', '\'];?>', $scoure);// 把编译后的内容保存成编译后的文件$comp = $this->compile_dir . '/'. $template . '.php';// 判断模板是否已经存在, 加上通过 文件修改的时间来判断,模板是否已经被修改过if ( file_exists($comp) && filemtime($tmp) < filemtime($comp) ) {return $comp;}file_put_contents($comp, $scoure);return $comp;                }}
?>

引入赋值和标签语法

smarty典型使用流程

<?php/*** 原理:* 分析html模板中的标签,生成相应的PHP文件* 再引入该PHP* * smarty流程:* 1. 引入smarty* 2. 实例化* 3. 配置[最基本的要配置模板目录和编译目录]*/// 引入smartyrequire('../smarty3/libs/Smarty.class.php');// 实例化$smarty = new Smarty();// 配置$smarty->template_dir    = './templates';$smarty->compile_dir = './compile';// 赋值$smarty->assign('title', 'T');$smarty->assign('content', 'C');// 编译$smarty->display('temp01.html');?>

smarty可以赋值为数值,数字等值,可以是数组.

VIEW:

<table style="border: 1px solid lightcyan;"><tr><td>姓名:</td><td>{$name}</td></tr><tr><td>年龄</td><td>{$age}</td></tr><tr><td>兵器</td><td>{$weapon}</td></tr>
</table><table style="border: 1px solid lightcyan;"><tr><td>姓名:</td><td>{$zf.name}</td></tr><tr><td>年龄</td><td>{$zf.age}</td></tr><tr><td>兵器</td><td>{$zf.weapon}</td></tr>
</table><table style="border: 1px solid lightcyan;"><tr><td>姓名:</td><td>{$guanyu[0]}</td></tr><tr><td>年龄</td><td>{$guanyu[1]}</td></tr><tr><td>兵器</td><td>{$guanyu[2]}</td></tr>
</table>

Controller

<?php// 引入smartyrequire('../smarty3/libs/Smarty.class.php');// 实例化$smarty = new Smarty();// 配置$smarty->template_dir    = './templates';$smarty->compile_dir = './compile';$user = array('name' => '刘备','age' => 28,'weapon' => '双剑');    // 赋值$smarty->assign($user);$zf = array('name' => '张飞','age' => 25,'weapon' => '矛');    $smarty->assign('zf', $zf);$guanyu = array('关羽', 25, '青龙');$smarty->assign('guanyu', $guanyu);// 编译$smarty->display('liubei.html');?>

smarty模板标签与css标签防止冲突

如果smarty默认定界符 {} 与 css {} 冲突
可以使用以下二种方法解决

  1. 修改smarty默认定界符{{}}

  2. 也可以用{literal}{/literal}标签,来告诉smarty,此处照常输出,不用解析

// 配置smarty的左右定界符
$smarty->left_delimiter = '{{';
$smarty->right_delimiter = '}}';          

<style type="text/css">{literal} table {background: pink;} {/literal}
</style>

模板变量来源

smarty标签变量的来源:
在模板中,{$title},则说明$title标签在被assign赋过值。

smarty的标签变量对应的来源,除了assign,还有那些?

  1. PHP中assign分配变量

  2. smarty的系统保留变量

  3. 从配置文件读取到的配置变量

assign

    // 引入require('../smarty3/libs/Smarty.class.php');// 实例化$smarty = new Smarty();// 配置$smarty->template_dir = './templates';$smarty->compile_dir = './compile'; // assign 赋值$smarty->assign('name', '罗隐');$smarty->assign('poem', '我未成名君未嫁,可能俱是不如人');// 编译$smarty->display('shiju.html'); 

系统保留变量

系统保留变量,不用赋值,能够自动获取

<p>{$smarty.get.id}</p>

$smarty.开头的标签,当成系统变量来解析,如:$smarty.get.id解析成<?php echo $_GET['id'] ?>

还有以下几个系统保留变量:

  • $smarty.post

  • $smarty.session

  • $smarty.cookies

常量如何显示:
$smarty.const.常量名

<p>{$smarty.const.HEI}</p>

配置文件读取配置变量

注意:

  1. 配置文件,一般以.conf做后缀

  2. 配置文件的写法是:选项=值

  3. 配置smarty的config_dir,并把配置文件放在该目录下.

配置文件:

site=pink
tel='13164889431'

获取配置文件中的变量:

// 引入:
{config_load file='site.conf'}// 显示
<div>
{$smarty.config.site}
</div><div>{#tel#}
</div>

append

连着往某个标签赋值多个值,可以使用append

赋值:

$smarty->append('color', 'tan'); // _tpl_vars['color'][] = 'tan'
$smarty->append('color', 'pink'); // _tpl_vars['color'][] = 'pink'

使用:

<p>{$color[0]}</p>
<p>{$color[1]}</p>

源码:

$data->tpl_vars[ $tpl_var ]->value[] = $value;

把一个值压入一个数组

smarty赋值时还能够引用赋值

assignByRef('title', $title); // _tpl_vars['title'] = &title; // 引用赋值

这个功能在PHP5以后,意义不大,PHP5以后是写时赋值

对象赋值和引用

对象赋值

class Human {public $name = 'zf';public $age = 23;public function say() {return 'HELLO WORLD';}}$man = new Human();$smarty->assign('man', $man);

显示:

<div>{$man->name}</div>
<div>{$man->age}</div>
<div>{$man->say()}</div>

模板的作用:分离PHP代码,让代码简洁,所以模板中的标签,应该尽量的只负责变量的输出.不要负责太多的逻辑判断,函数调用等.

简化模板配置

通过继承来简化模板配置

<?php/*** 使用对象继承的方式来完成smarty的配置*/class MySmarty extends Smarty {/*** 构造函数*/public function __construct() {// 调用父类的construct, 否则父类的一些设置就丢失了parent::__construct();$this->setTemplateDir('./templates');  // 模板文件位置$this->setCompileDir('./compile');  // 编译文件位置$this->setConfigDir('./conf');  // 配置文件位置}} ?>

标签数学运算

<div>{$age}</div>
<!-- 标签可以参与运算,但是不推荐 -->
<div>{$age + 2}</div><div>年纪差为:{$age - $diffAge}</div>

逻辑判断

IF标签要成对

{if $price < 10000 }
<div>{$color}</div>
{else}
<div>TAN</div>
{/if}

{if $smarty.get.today == 0 || $smarty.get.today == 7} 
<div>周日</div>
{elseif $smarty.get.today == 6}
<div>周六</div>
{else}
<div>工作日</div>
{/if}

在模板中使用逻辑判断的思考:
从分工角度看:模板只负责输出 ,不负责逻辑判断。
为什么还需要有逻辑判断? 在模板上进行逻辑判断,可以极大的简化工作.

smarty循环

for循环

for循环基本应用

赋值:

    $smarty->assign('start', 1);$smarty->assign('end', 9);

显示:

{for $i = $start to $end}{$i}{if $i % 3 == 0}<br/>{/if}
{/for}

<h3>1-100所有的奇数</h3>
{for $i=$start to 100}{if $i % 2 != 0 }<span>{$i}</span>{/if}
{/for}

循环总次数$i@total,循环索引$i@iteration

<h3>步长属性 控制</h3>    
<div>{for $i=$start to 100 step 2}{if $i@first == $start}<span style="color: cyan;">{$i}</span>{elseif $i@last == $i@total}<span style="color: tan;">{$i}</span>{else}    {$i}{/if}{if $i@iteration % 3 == 0}<br/>{/if}{/for}<div>循环总次数:{$i@total}</div><div>循环索引:$i@iteration</div><div>循环的第一次:$i@first</div><div>循环的最后一次:$i@last</div>
</div>    

foreach循环

foreach循环
典型场景,二维数组的循环
例如:新闻列表,会员列表,商品列表

赋值数据

<?php/*** foreach循环* 典型场景,二维数组的循环。* 例如:新闻列表,会员列表,商品列表*/    require('../smarty3/libs/Smarty.class.php');require('./MySmarty.class.php');$smarty = new MySmarty();// 链接数据库$conn = mysql_connect('127.0.0.1', 'root', '');// 设置字符集mysql_query('set names utf8', $conn);// 选择数据库mysql_query('use boolshop', $conn);// 查询数据$sql = "select cat_id, cat_name, intro from category limit 5";$result = mysql_query($sql, $conn);$category = array();while ( $row = mysql_fetch_assoc($result) ) {$category[] = $row;}// 关闭数据库连接mysql_close($conn);// 赋值    $smarty->assign($category);$smarty->display('foreach.html');    ?>

使用foreach:

<h2>商品栏目</h2>
<table border="1"><tr><td>序号</td><td>栏目名</td><td>栏目信息</td></tr>// {foreach from=$category key=key item=$g}{foreach $category as $k=>$g}<tr><td>{$g.cat_id}</td><td>{$g.cat_name}</td><td>{$g.intro}</td></tr>{/foreach}
</table>

循环总次数$i@total,循环索引$i@iteration

<h2>商品栏目</h2>
<table border="1"><tr><td>序号</td><td>栏目名</td><td>栏目信息</td></tr>{foreach $category as $k=>$g}<tr {if $g@iteration % 2 == 0} bgcolor="burlywood" {/if} {if $g@first == 1} bgcolor="gray" {/if}><td>{$g@iteration}</td><td>{$g.cat_name}</td>    <td>{$g.intro}</td></tr>{/foreach}
</table><div>索引:$g@iteration</div>
<div>首行:$g@first</div>
<div>尾行:$g@last</div>
<div>总条数:{$g@total}</div>

变量调节器

变量调节器:在模板中,修改变量的显示形式的一种功能.
变量调节器的本质是一个函数,这个函数,以标签对应的变量值为参数,然后运算,把返回值,显示在标签处.

内置变量调节器:

capitalize [首字符大写]
count_characters [字符计数]
cat [连接字符串]
count_paragraphs [计算段数]
count_sentences [计算句数]
count_words [计算词数]
date_format [格式化日期]
default [默认值]
escape [编码]
indent [缩进]
lower [小写]
nl2br [换行符替换成 <br />]
regex_replace [正则替换]
replace [替换]
spacify [插空]
string_format [字符串格式化]
strip [去除(多余空格)]
strip_tags [去除html标签]
truncate [截取]
upper [大写]
wordwrap [行宽约束]

使用变量调节器:

{foreach $goods as $key=>$g}
<tr><td>{$g.goods_id}</td><td>{$g.goods_name|truncate:15:'...'}</td><td>{$g.shop_price}</td><td>{$g.add_time|date_format:"%Y-%m-%d %H:%M:%S"}</td>
</tr>
{/foreach}

调节器的功能,在PHP中也能实现,也可以在模板中进行。比较合适在模板中进行。
体现了业务与显示的分离,尽量分离。

PHP就负责判断条件,并取出数据来。
至于显示的操作,应该尽量往"前"移(越接近用户).
MySQL-->PHP-->模板-->JavaScript

合适在MySQL存储原始数据,PHP中处理.
后台的数据尽量“原始”,不要带有样式,格式。显示的工作尽量靠前.

页面缓存

缓存,smarty重要概念。
缓存:把页面内容保存在磁盘上,下次访问相同页面,直接返回保存内容。减轻了数据库的压力。

smarty缓存的用法:

  1. 开启

  2. 配置缓存的生命周期

  3. 判断是否缓存成功并是否从数据库取出数据

  4. 输出

// 开启缓存 
$smarty->caching = true;// 设置缓存生命周期
$smarty->cache_lifetime = 3600;// 缓存的文件目录,用户存储缓存文件
$smarty->cache_dir = './cache';if ( !$smarty->isCached('cache.html') ) { // 判断文件是否缓存// 链接数据库$conn = mysql_connect('127.0.0.1', 'root', '');// 设置字符集mysql_query('set names utf8', $conn);// 选择数据库mysql_query('use boolshop', $conn);// 查询数据$sql = "select goods_id, goods_name, shop_price, add_time from goods limit 5";$result = mysql_query($sql, $conn);$goods = array();while ( $row = mysql_fetch_assoc($result) ) {$goods[] = $row;}// 关闭数据库连接mysql_close($conn);// 赋值    $smarty->assign('goods', $goods);echo '走了数据库';
}    $smarty->display('cache.html');    

局部缓存

smarty在页面缓存的情况下,可以设置部分内容不缓存。页面中有随机广告,时间,股票信息,不适宜缓存起来。

运行的时候,还是PHP代码,没有生成静态数据。

控制局部不缓存:

  • 在标签中控制,该标签不缓存。

// {$标签 nocache}
<h2>{$time|date_format:"%Y-%m-%d %H:%M:%S" nocache}</h2>
  • 控制一段标签不缓存

{nocache}
<h2>{$time|date_format:"%Y-%m-%d %H:%M:%S"}</h2>
<h2>{$time|date_format:"%Y-%m-%d %H:%M:%S"}</h2>
{/nocache}
  • 在PHP赋值时,就控制不缓存

$smarty->assign('time2', $time, true); // 第三个参数是 nocache,为true,说明不缓存

不缓存标签,要保证总能从PHP处得到值.

  • 调用函数

定义函数

function insert_welcome( $parm ) {return 'WELCOME HELLO' . ', AGE:' . $parm['age']; 
}

模板中使用:

<h2>{insert name="welcome" age=21}</h2>

单模版多缓存

场景:为商品模板设置缓存,当时从url接收的goods_id,当缓存后,所有商品都一样了,不合适。

能否为同一个模板,生成不同的缓存文件呢?
比如:根据ID的不同,来生成各个商品的缓存页面。
可以使用:单模板多缓存,
原理:生成缓存的时候,可以再传一个缓存ID。如果ID不同,则生成缓存文件不同。

// 编译    
$smarty->display('one_page.html', $goods_id);    

一般的,哪些参数要影响页面的内容,就需要把哪些参数,当成“缓存ID”。
例如:分页:page=3, 栏目:cat_id=3

多个参数影响:

// 编译    
$one_page = $goods_id + $page;  // 缓存ID,根据自定义规则计算
$smarty->display('one_page.html', $one_page);    // 缓存判断,也需要加缓存ID
if ( !$smarty->isCached('one_page'.html, $one_page) ) {
}

模板缓存:

<?phprequire('../smarty3/libs/Smarty.class.php');require('./MySmarty.class.php');$smarty = new MySmarty();// 开启缓存 $smarty->caching = true;// 设置缓存生命周期$smarty->cache_lifetime = 10;// 缓存的文件目录,用户存储缓存文件$smarty->cache_dir = './cache';$goods_id = $_GET['goods_id'] + 0;if ( !$smarty->isCached('one_page.html', $goods_id) ) {// 链接数据库$conn = mysql_connect('127.0.0.1', 'root', '');// 设置字符集mysql_query('set names utf8', $conn);// 选择数据库mysql_query('use boolshop', $conn);// 查询数据$sql = "select goods_name, shop_price, goods_desc from goods where goods_id=" . $goods_id;$result = mysql_query($sql, $conn);$goods = mysql_fetch_assoc($result);// 关闭数据库连接mysql_close($conn);// 赋值    $smarty->assign($goods);}    // 编译    $smarty->display('one_page.html', $goods_id);    ?>

强制删除缓存

简单删除缓存.
指定模板名,不指定缓存ID,则该模板对应的缓存都会被删除.
可以通过缓存ID来控制,模板对应的指定缓存删除掉.

<?php/*** 强制删除缓存*/require('../smarty3/libs/Smarty.class.php');require('./MySmarty.class.php');$smarty = new MySmarty();$goods_id = $_GET['goods_id'] + 0;// 参数模板名,和缓存ID$smarty->clearCache('one_page.html', $goods_id);echo '删除缓存成功';?>

出于调试目的,临时不缓存文件

$smarty->force_cache = true; // 强迫文件不缓存

数据对象

作用:数据分类,添加命名空间

不使用数据对象,所有数据都存储在smarty对象中.(重名就覆盖)
数据对象:把数据分类(不同类别的数据,重名不会覆盖)

<?phprequire('../smarty3/libs/Smarty.class.php');require('./MySmarty.class.php');$smarty = new MySmarty();$nav_top = array('首页', '商城', '男装');$nav_footer = array('友情链接', '备案');$smarty->assign('nav', $nav_top);$smarty->assign('nav', $nav_footer);  // 数据覆盖/*** smarty3引入一种新的概念,叫做数据对象。* 数据对象,就是一个装数据用的框。* * 靠2个数据对象,把2个数据对象里,各赋值一个同名的`nav`,2个`nav`对象互不干扰*/$smarty->display('news.html');?>

使用数据对象,命名空间

  1. 创建数据对象$smarty->createData();

  2. 数据挂载到该数据对象上.

  3. $smarty->dispaly();声明使用的数据

<?phprequire('../smarty3/libs/Smarty.class.php');require('./MySmarty.class.php');$smarty = new MySmarty();$nav_top = array('首页', '商城', '男装');$nav_footer = array('友情链接', '备案');//    $smarty->assign('nav', $nav_top);
//    $smarty->assign('nav', $nav_footer);/*** smarty3引入一种新的概念,叫做数据对象。* 数据对象,就是一个装数据用的框。* * 靠2个数据对象,把2个数据对象里,各赋值一个同名的`nav`,2个`nav`对象互不干扰*/// 创建一个数据对象$hdata = $smarty->createData();$fdata = $smarty->createData();// 使用数据对象$hdata->assign('nav', $nav_top);$fdata->assign('nav', $nav_footer);    // display时,要声明,这次使用,哪个数据对象。$smarty->display('header.html', $hdata);$smarty->display('news.html');$smarty->display('footer.html', $fdata);?>

对象注册

场景:在模板中,smartty标签中,允许调用对象的方法,如果方法是特殊方法,比如修改密码等方法。(模板调用特殊方法)

使用对象注册的方式来解决。

作用:允许调用的方法列表。

在View视图中:
注册对象的 变量:访问方法{zf->name}. 注意不加$,方法后不加()

<?phprequire('../smarty3/libs/Smarty.class.php');require('./MySmarty.class.php');$smarty = new MySmarty();class User {public $name = 'zf';public $age = 23;public function say() {return 'hello:' . $this->name;    }public function modPass() {return '修改密码成功';}}$zf = new User();//    $smarty->assign('zf', $zf);// 对象注册$smarty->registerObject('zf', $zf, array('say')); // 第三个参数可以控制允许调用的方法.$smarty->display('objLogin.html');?>

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title></title></head><body><h1>姓名:{zf->name}</h1><h2>年龄:{zf->age}</h2><p>SAY:{zf->say}</p><p>{zf->modPass}</p> <!-- 调用之后报错,已经不能调用该方法,限制方法不能调用 --><!-- 开发中,不建议使用 --></body>
</html>

模板继承

可以在父模板中,暂留{block name=""}{/block}

注意:

  1. 子模板第一句,先声明继承{extends file=''}

  2. 子模板的目的,只是填充父模板预留的block

父模板:

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>{block name='title'}父模板标题{/block}</title></head><body>{block name='header'}{/block}<hr />{block name='footer'}{/block}</body>
</html>

子模板1:

{extends file='tplExteds.html'}
{block name="title"}
<ul><li>嘻嘻哈哈</li><li>嘻嘻</li><li>哈哈</li>
</ul>
{/block}
{block name="header"}头部{/block}

子模板2:

{extends file='tplExted.html'}
{block name="footer"}2016年最后二天{/block}

变量调节器插件开发

调节器:

<?php/*** 调节颜色* @param {String} $string Smarty自动传递给进来,待调节的变量* @param {String} $color 参数值*/function Smarty_modifier_modcolor( $string, $color ) {return '<font color="' . $color . '">' . $string . '</font>';}?>
  1. 在smarty源码的目录中,plugins, 开发。

  2. 文件命名modifier.函数名.php

  3. 定义的调节器的函数名:Smarty_modifier_modcolor

display与fetch

display() 可以看成 echo fetch();
fecth()仅仅计算出应输出的结果,但是不输出,只把结果返回。

clipboard.png

一个PHP页面如何知道本身的输出结果: 使用缓冲区

利用fetch静态化

缓冲区的理解:

clipboard.png

fetch是如何知道当前页面的输出内容?
输出到缓冲区,在PHP的最后,读取缓冲区,就是本页面的内容。

打开缓冲区:ob_start();
读取缓冲区:ob_get_content();
清空缓冲区:ob_clean();
读取并清空:ob_get_clenan();

静态化:缓冲区+文件写操作

<?php// fetch 如何知道本页输出内容if ( file_exists('./html/fetch.html') ) {header('location: ./html/fetch.html');exit;}// 启动缓冲区ob_start();// 数据    echo 1 , '  ';echo 2 , '  ';echo 4 , '  ';// 读取缓冲区$html = ob_get_contents();// 清除缓冲区ob_clean();    // 写入文件file_put_contents('./html/fetch.html', $html);// 输出echo $html;?>

模板引擎特点

所有模板的共性:解析标签,解析成PHP

标签解析的分类:

  1. 最多的就是正则替换 。 例如:smarty2.X系列,quickskin

  2. 通过字符串函数来解析 例如:dede的模板类.

字符串解析

<?phpclass Mini {protected $left_delimiter = '{';protected $right_delimiter = '}'; protected $right_length = 1; // 右分隔符的长度public function __constrcut() {$this->right_length = strlen($this->right_delimiter);}protected $tags = array(); // 装载分析到的标签 // 编译public function parse( $file ) {$cont = file_get_contents('./templates/' . $file);$offset = 0;// 截取第一个字符 '{'while ( $poss = strpos($cont, $this->left_delimiter, $offset) !== false ) {// 取最后字符 '}'$pose = strpos($cont, $this->right_delimiter, $poss);// 截取标签$this->tags[] = substr($cont, $poss, $pose-$poss+$this->right_length);$offset = $pose + $this->right_length; }return $this->tags;}}
?>

变量的存储分类:

  1. 最多的是通过assign,把变量再次装载到模板对象中。
    如:smarty,thinkphp

  2. 只把模板解析出来,再包含模板
    如:discuzd的模板,把模板解析后,只返回模板的路径,再手动包含。(省略了assign过程,速度更快,显示的粗糙暴力)

语言分类:

  1. 绝大部分PHP

  2. C语言以扩展形式写的模板引擎(Blitz)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457359.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

读中文_挑战来了!康辉喊你读中文十级绕口令!

文章来源&#xff1a;央视频汉语桥木甬读桶不读涌&#xff0c;月农读脓不读胧。米更读粳不读梗&#xff0c;日青读晴不读睛。米宗读粽不读综&#xff0c;言丁读订不读钉。土竟读境不是镜&#xff0c;土平读坪不是评。耳令读聆不读岭&#xff0c;火登读灯不读澄。言甬读诵不读蛹…

ios 自定义键盘

由于项目需要&#xff0c;需要自定义键盘。ios系统键盘会缓存键盘输入&#xff0c;并保存在系统目录下的文件里&#xff0c;并且是明文存储&#xff0c;存在帐号密码泄漏风险。在别人代码基础上修改了下&#xff0c;美化了下界面&#xff0c;去掉了字符输入&#xff0c;加了点击…

【GOF23设计模式】迭代器模式

【GOF23设计模式】迭代器模式 来源&#xff1a;http://www.bjsxt.com/ 一、【GOF23设计模式】_迭代器模式、JDK内置迭代器、内部类迭代器 1 package com.test.iterator;2 /**3 * 自定义的迭代器接口4 */5 public interface MyIterator {6 void first(); //将游标指向第…

51单片机50个实例代码_【附代码】51单片机电子密码锁教程

简介大家好&#xff0c;这篇文章的内容是关于如何用51单片机来制作一个电子密码锁的教程&#xff0c;通过这篇教程可以让刚入门的朋友了解矩阵键盘、LCD1602的使用方法&#xff0c;以及密码输入和修改的程序介绍&#xff0c;我会对每个部分进行详细的介绍。首先我们来看一下这个…

8数据提供什么掩膜产品_博硕能为你提供什么产品?

自动喷漆设备应用于线条、木门、橱柜、楼梯、套房家具、办公家具、木饰面板、外墙保温装饰一体板板等产品领域&#xff0c;针对NC、PU、UV、水性漆和氟碳漆等不同种类的油漆&#xff0c;进行自动化喷涂和干燥作业。自动喷漆设备有多种规格型号&#xff0c;分为不同的喷涂方式。…

jsp页面验证码(完整实例)

项目结构如下&#xff0c;MyEclipse中新建一个Web Project&#xff0c;取名servlet 1、src下new一个servlet类 package com.servlet;import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOExcept…

开源oa_圈子哥推荐一款基于 Spring Boot 开发 OA 开源产品,学习/搞外快都是不二选择!...

点击上方蓝字关注「程序员的技术圈子」今天圈子哥给大家推荐一套Spring Boot 开发 OA系统&#xff0c;系统功能齐全&#xff0c;不管是用来学习或者搞外快都是不错的选择&#xff0c;clone下来吧&#xff01;办公自动化(OA)是面向组织的日常运作和管理&#xff0c;员工及管理者…

Libevent初探

Libevent 是一个用C语言编写的、轻量级的开源高性能网络库&#xff0c;主要有以下几个亮点&#xff1a;事件驱动&#xff08; event-driven&#xff09;&#xff0c;高性能;轻量级&#xff0c;专注于网络&#xff0c;不如 ACE 那么臃肿庞大&#xff1b;源代码相当精炼、易读&am…

特别慢_背什么都特别慢,该怎么提高记忆力?

考研是一项全方位的比拼&#xff0c;除了每天进行知识点的复习&#xff0c;还要做题、总结&#xff0c;最后还得进行背诵记忆&#xff0c;其实什么科目都需要背的&#xff0c;就算数学&#xff0c;该记的概念和公式也是要记忆的&#xff0c;因为会做题更快&#xff0c;提高效率…

第三章 中间件,3.1 万亿级数据洪峰下的分布式消息引擎(作者:冯嘉、誓嘉、尘央、牟羽)...

3.1 万亿级数据洪峰下的分布式消息引擎 前言 通过简单回顾阿里中间件(Aliware)消息引擎的发展史&#xff0c;本文开篇于双11消息引擎面临的低延迟挑战&#xff0c;通过经典的应用场景阐述可能会面临的问题 - 响应慢&#xff0c;雪崩&#xff0c;用户体验差&#xff0c;继而交易…

Linux目录结构和常用命令

一、Linux目录结构 你想知道为什么某些程序位于/bin下&#xff0c;或者/sbin&#xff0c;或者/usr/bin&#xff0c;或/usr/sbin目录下吗&#xff1f;例如&#xff0c;less命令位于/usr/bin目录下。为什么没在/bin中&#xff0c;或/sbin&#xff0c;或/usr/sbin目录中&#xff1…

挂载nfs文件系统_综合架构-day38-NFS服务补充

1.如何让nfs永久挂载-2种方法开机自启动文件1.vim /etc/rc.d/rc.local需要修改执行权限chmod x /etc/rc.d/rc/localmount -t nfs 172.16.1.31:/upload/ /mnt/2.vim /etc/fstab172.16.1.31:/upload /mnt nfs defaults 0 02.exportfs 加载配置生效&#xff0c;等价于优雅重启[15:…

A Neural Algorithm of Artistic Style

本系列文章由 yhl_leo 出品&#xff0c;转载请注明出处。 文章链接&#xff1a; http://blog.csdn.net/yhl_leo/article/details/53931536 1. 资源 Paper: A Neural Algorithm of Artistic StyleTensorFlow version in GitHub: anishathalye/neural-styleCaffe version in GitH…

CSS布局奇淫技巧之--各种居中

居中是我们使用css来布局时常遇到的情况。使用css来进行居中时&#xff0c;有时一个属性就能搞定&#xff0c;有时则需要一定的技巧才能兼容到所有浏览器&#xff0c;本文就居中的一些常用方法做个简单的介绍。 注&#xff1a;本文所讲方法除了特别说明外&#xff0c;都是兼容I…

手写数字识别中多元分类原理_广告行业中那些趣事系列:从理论到实战BERT知识蒸馏...

导读&#xff1a;本文将介绍在广告行业中自然语言处理和推荐系统实践。本文主要分享从理论到实战知识蒸馏&#xff0c;对知识蒸馏感兴趣的小伙伴可以一起沟通交流。摘要&#xff1a;本篇主要分享从理论到实战知识蒸馏。首先讲了下为什么要学习知识蒸馏。一切源于业务需求&#…

linux zip/unzip命令

2019独角兽企业重金招聘Python工程师标准>>> 语  法&#xff1a;zip [-AcdDfFghjJKlLmoqrSTuvVwXyz$][-b <工 作目录>][-ll][-n <字 尾字符串>][-t <日 期时间>][-<压 缩效率>][压 缩文件][文件...][-i <范本样式>][-x <范本样式…

在Windows下不使用密码远程登陆Linux

在登陆Linux进行管理的时候我们通常会使用用户名和密码进行登陆&#xff0c;这样一来是比较麻烦&#xff0c;二来是不安全&#xff0c;为了解决这个问题&#xff0c;我们可以使用公私钥 (public keys和private keys)进行认证。简单来说公钥存放在服务器上&#xff0c;私钥存放在…

Core Data

简介 Core Data是iOS5之后才出现的一个框架&#xff0c;它提供了对象-关系映射(ORM)的功能&#xff0c;即能够将OC对象转化成数据&#xff0c;保存在SQLite数据库文件中&#xff0c;也能够将保存在数据库中的数据还原成OC对象。在此数据操作期间&#xff0c;我们不需要编写任何…

2017将转行进行到底

2016 年说着转行&#xff0c;最后还是在匆匆中找了一份老本行&#xff0c;此刻的心情还是无爱&#xff0c;毕竟螺丝一直分不清啊&#xff0c;不喜欢就是不喜欢。看了django的教程&#xff0c;不得不感叹国外的书写的相对优秀一点&#xff0c;《learning django web development…

mysql非主键索引_主键索引和非主键索引的区别

1. 什么是最左前缀原则&#xff1f;以下回答全部是基于MySQL的InnoDB引擎例如对于下面这一张表如果我们按照 name 字段来建立索引的话&#xff0c;采用B树的结构&#xff0c;大概的索引结构如下如果我们要进行模糊查找&#xff0c;查找name 以“张"开头的所有人的ID&#…