z-blogphp173相关变量

<body>

{time()}

{php}<?php

//php必须和标签在同一行

echo date('Y-m-d H:i:s');

?>{/php}

系统  我是搜索页<br>

博客网址:{$host}<br>

博客标题:{$name}<br>

博客副标题:{$subname}<br>

主题名称:{$theme}<br>

样式名称:{$style}<br>

版权说明:{$copyright}<br>

Z-BlogPHP 版本号:{$version}<br>

Z-BlogPHP 版本信息:{$zblogphp}<br>

Z-BlogPHP 链接(长):{$zblogphphtml}<br>

Z-BlogPHP 链接(短):{$zblogphpabbrhtml}<br>

网站语言:{$language}<br>

页面头部变量:{$header}<br>

页面尾部变量:{$footer}<br>

页面类型:{$type}<br>

当前页面页码:{$page}<br>

社会化评论区:{$socialcomment}<br>

cookie的路径:{$cookiespath}<br>

网站目录物理路径:{$path}<br>

<br>

<br>

module-by-name 模块的一些信息<br>

导航栏:<br>

内部ID:{$modules["navbar"].ID}<br>

模块名称:{$modules["navbar"].Name}<br>

文件名:{$modules["navbar"].FileName}<br>

模块内容:{$modules["navbar"].Content}<br>

htmlID:{$modules["navbar"].HtmlID}<br>

模块类型:{$modules["navbar"].Type}<br>

ul类型模块显示的最大列数:{$modules["navbar"].MaxLi}<br>

模块属性 system=系统模块,theme=主题模块,plugin=插件模块:{$modules["navbar"].Source}<br>

是否隐藏标题:{$modules["navbar"].IsHideTitle}<br>

<br>

{if $pagebar}

分页<br>

分页长度:{$pagebar.PageBarCount}<br>

每页显示文章数量:{$pagebar.PageCount}<br>

总页码数:{$pagebar.PageAll}<br>

当前页码:{$pagebar.PageNow}<br>

起始页码:{$pagebar.PageFirst}<br>

页尾页码:{$pagebar.PageLast}<br>

上一页ID:{$pagebar.PagePrevious}<br>

下一页ID:{$pagebar.PageNext}<br>

上一页Url:{$pagebar.prevbutton}<br>

下一页Url:{$pagebar.nextbutton}<br> 

{/if}

{if $type == 'author'}

<br>

用户页? author user article.Author<br>

用户页面链接:{$author.Url}<br>

用户名:{$author.Name}<br>

用户别名:{$author.Alias}<br>

用户静态名:{$author.StaticName}<br>

用户级别:{$author.Level}<br>

用户级别名:{$author.LevelName}<br>

用户邮箱:{$author.Email}<br>

用户主页:{$author.HomePage}<br>

用户摘要:{$author.Intro}<br>

用户头像:{$author.Avatar}<br>

用户股发表文章数量:{$author.Articles}<br>

用户创建页面数:{$author.Pages}<br>

用户发表评论数:{$author.Comments}<br>

用户上传文件数:{$author.Uploads}<br>

{/if}

{if $type == 'tag'}

<br>

标签页?:<br>

标签名:{$tag.Name}<br>

标签链接:{$tag.Url}<br>

标签下文章数:{$tag.Count}<br>

{/if}

{if $type == 'category'}

<br>

分类页? category article.Category<br>

分类ID:{$category.ID}<br>

分类名称:{$category.Name}<br>

分类别名:{$category.Alias}<br>

分类链接:{$category.Url}<br>

分类文章数量:{$category.Count}<br>

分类摘要:{$category.Intro}<br>

分类序号:{$category.Order}<br>

分类层级:{$category.Level}<br>

分类的顶级ID:{$category.RootID}<br>

分类的上级ID:{$category.ParentID}<br>

分类的上一级类实例:{$category.Parent}<br>

分类所用模板:{$category.Template}<br>

分类下文章所用模板:{$category.LogTemplate}<br>

分类扩展数据:{$category}<br>

子分类实例数组:{if $category.SubCategorys == null} 子分类为空{/if}<br>

{/if}

<br>

模块 module-content<br>

导航栏:{module:navbar}<br>

日历:{module:calendar}<br>

控制面板:{module:controlpanel}<br>

网站分类:{module:catalog}<br>

搜索:{module:searchpanel}<br>

最新留言:{module:comments}<br>

文章归档:{module:archives}<br>

站点信息:{module:statistics}<br>

网站收藏:{module:favorite}<br>

友情链接:{module:link}<br>

图标汇集:{module:misc}<br>

作者列表:{module:authors}<br>

最近发表:{module:previous}<br>

标签列表:{module:tags}<br>

文章页<br> 搜索结果页  列表  分类列表页

文章ID:{$article.ID}<br>

文章标题:{$article.Title}<br>

文章别名:{$article.Alias}<br>

文章别名或标题:{$article.AliasFirst}<br>

文章链接:{$article.Url}<br>

文章是否置顶:{$article.IsTop}<br>

文章置顶类型:{$article.TopType}<br>

文章摘要:{$article.Intro}<br>

文章正文:{$article.Content}<br>

文章第一张图片:{if $article->AllImages}{$article.AllImages[0]}{/if}<br>

文章图片计数:{$article.ImageCount}<br>

文章第一张图片的缩略图:{if $article->AllImages}{$article.Thumbs(640, 360, 1, false)[0]}{/if}<br>

文章状态(数字):{$article.Status}<br>

文章状态(名):{$article.StatusName}<br>

是否禁止评论:{$article.IsLock}<br>

文章评论数:{$article.CommNums}<br>

文章浏览数:{$article.ViewNums}<br>

文章发布时间:{$article.Time("PostTime","Y-m-d H:i:s")}<br>

文章创建时间:{$article.Time("CreateTime","Y-m-d H:i:s")}<br>

文章更新时间:{$article.Time("UpdateTime","Y-m-d H:i:s")}<br>

文章分类数据:{$article.Category}<br>

文章作者数据:$article {"ID":"15","CateID":"1","AuthorID":"1","Tag":"","Status":"0","Type":"0","Alias":"","IsTop":"0","IsLock":false,"Title": Intro Content<br>

文章标签数组:<br>

第一个标签对象:{$article.FirstTag}<br>

文章标签计数:{$article.TagsCount}<br>

逗号分隔的文章标签:{$article.TagsName}<br>

文章类型:{$article.Type}<br>

文章类型:{$article.TypeName} ARTICLE 为普通文章,PAGE 为普通页面。<br>

<br>

{foreach $comments as $key => $comment}

{foreach $comment.Comments as $comment}

有子评论

{/foreach}

评论<br>

评论ID:{$comment.ID}<br>

评论楼号:{$comment.FloorID}<br>

评论层级:{$comment.Level}<br>

评论父ID:{$comment.ParentID}<br>

评论根ID:{$comment.RootID}<br>

评论所属文章/页面ID:{$comment.LogID}<br>

评论作者:{$comment.Author.Name}<br>

评论作者网址:{$comment.Author.HomePage}<br>

评论作者邮箱:{$comment.Author.Email}<br>

评论作者头像地址:{$comment.Author.Avatar}<br>

评论所属文章的链接:{$comment.Post.Url}<br>

评论所属文章的标题:{$comment.Post.Title}<br>

评论正文:{$comment.Content}<br>

评论者IP:{$comment.IP}<br>

评论者客户端信息:{$comment.Agent}<br>

评论发布时间:{$comment}<br>

{/foreach}


php调用过程中的堆栈代码段
admin 2024年09月27日 0 82 未分类

$backtrace = debug_backtrace();

    // 移除当前函数调用的层级

    echo "调用栈信息:\n";

    foreach ($backtrace as $level => $call) {

        $className = (isset($call['class'])) ? $call['class'] : '';

        $methodName = $call['function'];

        $fileName = $call['file'];

        $lineNumber = $call['line'];

        echo "层级 {$level}:\n";

        echo "    类名:{$className}\n";

        echo "    方法名:{$methodName}\n";

        echo "    文件名:{$fileName}\n";

        echo "    行号:{$lineNumber}\n";

        echo "<br>";

    }


为代码添加看门狗功能

看门狗是一种能够在程序正常执行出现异常时自动重置程序的功能

在需要长期执行的代码中代码总是不可避免的因为某些原因导致执行异常,如果不能从异常中恢复正常执行过程可能会导致项目的停止。所以为程序代码添加上看门狗功能是很有用的。

在51单片机中,头文件并没有定义这个寄存器地址,不过查看单片机手册可以发现是有这个功能的(在STM32单片机中可以直接使用),看门狗的寄存器地址是 0xe1,在代码中直接定义即可

sfr WDT_CONTR = 0xe1;

这个寄存器使用0-5位共6位可以设置

其中

第6位是看门狗是否开启位,为1打开看门狗

第5位是看门狗清零位,设置为1表示重新计数,硬件会自动将此位清零

第4位是看门狗执行环境,设置为1表示在空闲模式计数,0为在空闲模式不计数

第1-3位是看门狗的定时器预分配值,也就是看门狗重置的时长,超过这个时间没有重置看门狗的寄存器就会直接导致程序被重置

以下是12M晶振下的溢出时间

000 = 2分频 = 65.5毫秒

001 = 4分频 = 131毫秒

010 = 8分频 = 262.1毫秒

011 = 16分频 = 524.2毫秒

100 = 32分频 = 1.0485秒

101 = 64分频 = 2.0971秒

110 = 128分频 = 4.1943秒

111 = 256分频 = 8.3886秒

计算公式 = (12 X 预分频 X 32768)/12000000

所以这里设置为 0x111110 = 0x3e;

表示开启看门狗,设置为重新计数,设置为在空闲模式计数,预分频110=大概4秒溢出时间

代码如下:


#include <reg52.h>

//看门狗的寄存器地址

sfr WDT_CONTR = 0xe1;

//LED灯展示效果

#define LED P2

unsigned char P32_STATUS = 1; //外部中断1的状态

sbit K1 = P1^4;

sbit K2 = P1^5;

sbit K3 = P1^6;

sbit K4 = P1^7;

sbit K5 = P3^5;

void delay10ms(unsigned int);

void main(void){

unsigned char num = 0;

WDT_CONTR = 0x3e;

IT0 = 1;

EX0 = 1;  //允许中断

IT1 = 1;

EX1 = 1;  //允许中断

EA = 1;   //开启总中断

//开机闪烁

P2 = 0xff;

delay10ms(100);

P2 = 0xaa;

delay10ms(100);

P2 = 0x55;

delay10ms(100);

while(1){

//如果看门狗没有起效,将在这里死循环

P2 = num;

num++;

delay10ms(10);

WDT_CONTR = 0x3e;//重置看门狗计数值,防止程序被重置

}

}

void delay10ms(unsigned int c)

{

    unsigned char a,b;

    for(;c>0;c--)

        for(b=38;b>0;b--)

            for(a=130;a>0;a--);

}


51单片机模拟串口通信
admin 2024年09月27日 0 73 经验心得

使用普通IO口来模拟串口通信,串口通信中使用两根信号线来进行发送和接收,RXD获取数据TXD发送数据,两个设备的RXD和TXD要交叉连接

然后发送频需要根据波特率来设置,比如9600的波特率在11.0592Mhz晶振的单片机中的发送延时就是104us

也就是发送1比特为需要的高电平时间,这个延时需要比较精确否则就有可能通信失败

USART串口协议如下,开始是空闲信号线高电平变为低电平且保存104us(以9600波特率为例)为开始信号,之后依次发送每一位比特的高低电平,发送是以低电平开始发送,直到发送完8字节,然后如果没有奇偶校验等的话就是结束信号,将电平保存高电平大于104us即为结束信号

接收和发送情况是一样的,接收的数据是从低字节到高字节顺序获取每一位

怎么判断接收完成?因为结束标志完毕之后如果继续发送数据,电平会被拉低,所以只需要获取到结束标志之后循环判断一定的时间(大于104us,比如取110us),如果在次判断是低电平说明数据还有需要继续接收,否则就是接收完毕。

代码比较简单,一般去读串口数据都是取延时中值的结果,(比如104us的一半时间52us,电平为低时延时52us,之后间隔104us)这样比较准确,也可以使用中断的方式来获取。

关于缓存数组,因为串口数据的发送时间间隔很短,没有多余的时间用于对数据的处理,所以一般都是先将数据放入到一个缓存中,待数据接收完毕之后再处理,否则可能会导致不能及时获取数据导致数据丢失。

代码如下,经过测试可以完成发送和接收:


#include <reg52.h>

#include <intrins.h>

sbit RXD2 = P2^2;

sbit TXD2 = P2^3;

unsigned char str[21] = "http://192.168.0.112/";

unsigned char buffer[50] = {0}; //接收缓存

int getbuffernum,putbuffernum,num;

void delay(void);

void delay2(void);

void Delay10ms(unsigned int c);

void putdata(unsigned char str);

void getdata(void);

void main(){

unsigned char i;

  while(1){

getbuffernum = 0;

//读取串口数据

if(RXD2 == 0){

  int maxnum = 1000;

  while(maxnum--){

  if(RXD2 == 0){

  getdata();

  maxnum = 1000;

}

  };

}else{

  if(buffer[0] != 0){

for(i=0;i<49;i++){

if(buffer[i] != 0){

putdata(buffer[i]);

buffer[i] = 0;

}else{

break;

}

}

getbuffernum = 0;

putdata(0x0d);

putdata(0x0a);

}

num = 0;

}

  }

}

void getdata(){

unsigned int i;

unsigned char str = 0x0;

if(RXD2 == 0){//起始信号

num = 0;

delay2();

if(RXD2 == 0){

//接收数据

for(i=0;i<8;i++){

str >>= 1;

delay();

if(RXD2 == 1){

str |= 0x80;

}

}

}

delay();

buffer[getbuffernum] = str;

getbuffernum++;

}else{

num++;

}

}

void putdata(unsigned char str){

TXD2 = 0;

delay();

TXD2 = str & 0x1;

delay();

str >>= 1;

TXD2 = str & 0x1;

delay();

str >>= 1;

TXD2 = str & 0x1;

delay();

str >>= 1;

TXD2 = str & 0x1;

delay();

str >>= 1;

TXD2 = str & 0x1;

delay();

str >>= 1;

TXD2 = str & 0x1;

delay();

str >>= 1;

TXD2 = str & 0x1;

delay();

str >>= 1;

TXD2 = str & 0x1;

delay();

TXD2 = 1;

delay();

}

//104us 9600波特率是通过计算得出来的 num为7 表示 104us 误差 0.05us

void delay(){

//i=134 2400 (415us)通过 i=67 4800 (208us)通过 i=32 9600 (104us)通过

  unsigned char i;

  for(i=0;i<134;i++){} 

}

void delay2(){

  unsigned char i;

  for(i=0;i<67;i++){} 

}

////误差 0us

void Delay10ms(unsigned int c){

unsigned char a,b;

    for(;c>0;c--){

        for(b=38;b>0;b--){

            for(a=130;a>0;a--){

}

}

}

}


教学篇-点亮数码管

数码管每个字段都是笔画都是和P0口的八个IO口相连的,且和其他数码管相连,所以一般情况下数码管会同时亮起,因为数码管另一端是接地的,所以IO口需要输出高电平

HC6800-MS开发板中四个数码管另一端从左到右是分别接在P1^3 - P1^0,也是需要输出高电平,这四个IO口控制数码管中的通断

#define GPIO_DIG  P0 //段选

sbit LED1 = P1^3;

sbit LED2 = P1^2;

sbit LED3 = P1^1;

sbit LED4 = P1^0;

unsigned char code DIG_CODE[17] = {

0x3f^0x06^0x5b^0x4f^0x66^0x6d^0x7d^0x07^

0x7f^0x6f^0x77^0x7c^0x39^0x5e^0x79^0x71^0x01};

//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、.的显示码

最后

LED1 = 1;

GPIO_DIG = DIG_CODE[m];

就可以显示第一个数码管的值了,因为默认P1口是输出高电平的,所以其它管应该设置为0低电平

for(i=0;i<10;i++);

GPIO_DIG = 0x00; //消影

以上代码是指演示一些时间后将数码管值0来关闭消除上一个显示的余光

最后代码如下,是显示4个数码管同时变化的,但是并不太行,后续再研究

!code=

#include<reg52.h>

#define GPIO_DIG  P0 //段选

sbit LED1 = P1^3;

sbit LED2 = P1^2;

sbit LED3 = P1^1;

sbit LED4 = P1^0;

char num;

unsigned char code DIG_CODE[17] = {

0x3f^0x06^0x5b^0x4f^0x66^0x6d^0x7d^0x07^

0x7f^0x6f^0x77^0x7c^0x39^0x5e^0x79^0x71^0x01};

//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、.的显示码

void Delay10ms(unsigned int);

void main(void){

unsigned char n^i;

TMOD = 0x01;   //定时器0 工作方式一

TH0 = (65536 - 300)/256;   //定时1ms

TL0 = (65536 - 300)%256;

TR0 = 1;   //打开定时器0中断

ET0 = 1;

EA  = 1; //开总中断

while(1){

for(n=0;n<5;n++){

num = n;

Delay10ms(100);

}

}

}

void Timer0Interrupt() interrupt 1{

unsigned char i^m;

TH0 = (65536 - 300)/256;   //定时1ms

TL0 = (65536 - 300)%256;

m = num;

LED1 = 1;

GPIO_DIG = DIG_CODE[m];

for(i=0;i<10;i++);

GPIO_DIG = 0x00; //消影

LED1 = 0;

LED2 = 1;

GPIO_DIG = DIG_CODE[m+1];

for(i=0;i<10;i++);

GPIO_DIG = 0x00;

LED2 = 0;

LED3 = 1;

GPIO_DIG = DIG_CODE[m+2];

for(i=0;i<10;i++);

GPIO_DIG = 0x00;

LED3 = 0;

LED4 = 1;

GPIO_DIG = DIG_CODE[m+3];

for(i=0;i<10;i++);

GPIO_DIG = 0x00;

LED4 = 0;

}

void Delay10ms(unsigned int c)  //误差 0us

{

    unsigned char a^b;

    for(;c>0;c--)

        for(b=38;b>0;b--)

            for(a=130;a>0;a--);

}

!codend=


教学篇-点亮第一个LED灯

#include<reg52.h> 架子头文件,里面是一些定义的设备的地址

sbit 定义一个为一个位,从原理图可以看到 P20-27连接着D1-D8的负极,所以对应位设置为0即可点亮对应的LED灯,P2^7 表示选择D8 LED灯

然后就是最简单的循环代码了

代码如下

#include<reg52.h> //声明头文件

sbit LED1=P2^7;   //位操作,P2^0替换为LED1

void Delay(unsigned int a); //延时函数声明

void main() //主函数

{

while(1)

{

LED1=0; //低电平点亮

Delay(5000); //延时

LED1=1; //高电平熄灭

Delay(5000); //延时

}

}

//不准确的延时函数

void Delay(unsigned int a)

{

unsigned char b;

for(;a>0;a--)

{

for(b=110;b>0;b--);

}

}


flex 和 grid 的一些知识点

display:flex; 弹性布局,只对下一级元素有效

justify-content:flex-start; 左对齐

justify-content:flex-end; 右对齐

justify-content:flex-center; 居中对齐

justify-content:space-around; 平分空间

justify-content:space-between; 两端对齐,各个元素之间空隙相同

align-items:flex-center; 容器上下居中

align-items:flex-stretch; 容器上下居中且子元素占满容器高度,子容器不设置高度

display:grid; 网格布局,只对下一级元素有效,默认容器内的内容填满空间

grid-template-colums 定义每列宽度

grid-template-row 定义每行高度

repeat(auto-fill,30px) 重复填充,每个格子30px

grid-template-columns:1fr 2fr; 定义两列,第二列宽度是第一列的两倍

grid-template-columns:repeat(auto-fit,minmax(100px,1fr)); 元素平均分,如果宽度不够就换行

minmax() auto

grid-row-gap 行间距

grid-column-gap 列间距

grid-gap:5px; 行间距和列间距一样

grid-area:span 2 / span 1; 在该元素位置开始 占两行1列


实现html字符串获取子元素以及清空子元素

获取子元素,包含自身

$dom = new DOMDocument();

$dom->loadHTML('<?xml encoding="UTF-8">' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

$xpath = new DOMXPath($dom);

// 使用 XPath 选择具有特定 codev_name 属性的 div

$div = $xpath->query('//div[@codev_name="列表组件"]')[0];

// 使用 saveHTML 方法获取包含 div 元素的完整 HTML 字符串

$content = $dom->saveHTML($div);

// 输出结果

echo $content;


清空所有子节点


$dom = new DOMDocument();

$dom->loadHTML('<?xml encoding="UTF-8">' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

$xpath = new DOMXPath($dom);

// 使用 XPath 选择具有特定 codev_name 属性的 div

$div = $xpath->query('//div[@codev_name="列表组件"]')[0];

// 清空 div 的所有子节点

while ($div->firstChild) {

    $div->removeChild($div->firstChild);

}

// 现在 div 是空的,但我们可以获取包含它的完整 HTML 字符串(没有子节点)

$content = $dom->saveHTML($div);

// 输出结果

echo $content;


标签1 ( 15 )
标签2 ( 12 )
标签3 ( 4 )
标签4 ( 2 )
标签5 ( 7 )
标签6 ( 5 )
标签 ( 2 )