找到
11
篇与
PHP
相关的结果
-
Typecho插件开发手册 一、插件的基本结构 在 Typecho 中,插件通常是一个独立的 PHP 文件,默认放置在usr/plugins/目录下。插件文件名即为插件名,插件类名也应与文件名相同。插件必须实现 Typecho_Plugin_Interface 接口。 基本结构: <?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; /** * 插件的描述信息 * * @package PluginName */ class PluginName_Plugin implements Typecho_Plugin_Interface { // 插件激活方法 public static function activate() {} // 插件停用方法 public static function deactivate() {} // 插件配置面板 public static function config(Typecho_Widget_Helper_Form $form) {} // 个人用户的配置面板 public static function personalConfig(Typecho_Widget_Helper_Form $form) {} // 实现的插件功能方法 // ... }说明 Typecho_Plugin_Interface:插件类必须实现该接口,包含 activate、deactivate、config、personalConfig 四个方法。 activate:插件激活时调用,用于注册插件方法、初始化数据等。 deactivate:插件停用时调用,用于清理数据、注销插件方法等。 config:插件的配置界面,用于在后台展示插件的设置选项。 personalConfig:针对个人用户的配置界面。 二、激活插件 在 activate 方法中,可以进行以下操作: 注册插件方法 :使用 Typecho_Plugin::factory 注册插件的方法到指定的 Hook Point。 创建数据库表 :如果插件需要额外的数据表,可以在激活时创建。 初始化数据 :初始化插件所需的数据或配置。 public static function activate() { // 注册插件方法到 Hook Point Typecho_Plugin::factory('Widget_Archive')->beforeRender = array('PluginName_Plugin', 'beforeRender'); // 返回激活成功的信息 return _t('插件已激活'); } 三.停用插件 在deactivate方法中,可以进行以下操作: 注销插件方法:清理注册的插件方法(Typecho 会自动处理)。 删除数据库表:如果插件创建了额外的数据表,可以选择在停用时删除。 清理数据:清理插件的配置信息或缓存。 四、定义插件的配置界面 在 config 方法中定义插件的配置选项。 public static function config(Typecho_Widget_Helper_Form $form) { // 添加一个文本框 $text = new Typecho_Widget_Helper_Form_Element_Text('text', NULL, '默认值', _t('文本框标签'), _t('文本框提示')); $form->addInput($text); // 添加一个单选框 $radio = new Typecho_Widget_Helper_Form_Element_Radio('radio', array('1' => '选项1', '2' => '选项2'), '1', _t('单选框标签')); $form->addInput($radio); // 添加一个复选框 $checkbox = new Typecho_Widget_Helper_Form_Element_Checkbox('checkbox', array('1' => '选项1', '2' => '选项2'), NULL, _t('复选框标签')); $form->addInput($checkbox); }说明: 使用 Typecho_Widget_Helper_Form_Element_* 类来创建不同类型的表单元素。 调用 $form->addInput() 方法将元素添加到配置界面。 五、处理插件的用户配置 在插件的方法中,可以通过Helper::options()->plugin('PluginName')获取用户的配置信息。 public static function someMethod() { $options = Helper::options()->plugin('PluginName'); $textValue = $options->text; // 获取文本框的值 // ... }说明: Helper::options():获取全局的配置对象。 plugin('PluginName'):获取指定插件的配置信息。 六、注册插件方法(Hook Point) 在 activate 方法中,使用 Typecho_Plugin::factory 注册插件的方法到指定的 Hook Point。 public static function activate() { Typecho_Plugin::factory('Widget_Archive')->beforeRender = array('PluginName_Plugin', 'beforeRender'); }说明: 具体插入点可以参考文章后半段,有专门介绍各插入点的作用及位置 Typecho_Plugin::factory('类名')->方法名:指定要拦截的类和方法(Hook Point)。 array('PluginName_Plugin', '方法名'):插件的方法回调。 七、定义自定义路由 如果插件需要自定义 URL 路由,可以在activate 方法中定义。 public static function activate() { // 添加自定义路由 Helper::addRoute('plugin_route', '/plugin/route/', 'PluginName_Action', 'actionMethod'); } public static function deactivate() { // 删除自定义路由 Helper::removeRoute('plugin_route'); }Helper::addRoute:添加自定义路由。 第一个参数:路由名称。 第二个参数:路由规则(URL 模式)。 第三个参数:处理该路由的类名。 第四个参数:处理方法。 Helper::removeRoute:删除自定义路由。 八、加载插件的类和方法 如果插件包含多个类或文件,可以通过require_once或自动加载的方式引入。 // 在插件的主文件中 require_once 'libs/Helper.php'; // 使用命名空间和自动加载 spl_autoload_register(function ($class) { $prefix = 'PluginName\\'; $base_dir = __DIR__ . '/src/'; $len = strlen($prefix); if (strncmp($prefix, $class, $len) !== 0) { return; } $relative_class = substr($class, $len); $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; if (file_exists($file)) { require $file; } }); require_once:直接引入文件。 spl_autoload_register:注册自动加载函数,按照命名空间和目录结构自动加载类。 九、文件载入与资源管理 插件可能需要加载 CSS、JS 文件或其他资源,可以通过以下方式实现。 在模板中加载资源: // 在插件的方法中 public static function header() { $cssUrl = Helper::options()->pluginUrl . '/PluginName/assets/style.css'; echo '<link rel="stylesheet" type="text/css" href="' . $cssUrl . '">'; } public static function footer() { $jsUrl = Helper::options()->pluginUrl . '/PluginName/assets/script.js'; echo '<script type="text/javascript" src="' . $jsUrl . '"></script>'; }注册到 Hook Point: public static function activate() { Typecho_Plugin::factory('Widget_Archive')->header = array('PluginName_Plugin', 'header'); Typecho_Plugin::factory('Widget_Archive')->footer = array('PluginName_Plugin', 'footer'); } Helper::options()->pluginUrl:获取插件目录的 URL。 header、footer:在页面的头部和尾部输出内容。 十、模板的使用与扩展 插件可以自定义模板,或者扩展主题的模板功能。在插件目录中创建模板文件: 创建themes目录 :在插件目录下创建themes目录,用于存放模板文件。 编写模板文件 :例如,创建themes/plugin-template.php 在插件中调用模板: public static function renderTemplate() { $template = __DIR__ . '/themes/plugin-template.php'; if (file_exists($template)) { include $template; } else { echo '模板文件不存在'; } }在路由处理方法中调用: public function actionMethod() { self::renderTemplate(); } 十一、完整的插件示例 usr/ └── plugins/ └── HelloWorld/ ├── HelloWorld_Plugin.php ├── Action.php ├── assets/ │ ├── style.css │ └── script.js └── themes/ └── hello.php十二、钩子(Hook)插入点 在 Typecho 插件开发中,可以通过 Typecho_Plugin::factory('类名')->方法名的形式来拦截和扩展 Typecho 的核心功能。以下是所有可用的插入位置(Hook Points),按照类名分类,并注明调用的位置及意义。 十三、插入位置的定义方式 插入位置通常是通过以下几种方式定义的: 方法(Method): 在 Typecho 的核心类中,某些方法被定义为插入位置。例如,Widget_Contents_Post_Edit类中的insert方法就是一个插入位置。 插件可以通过Typecho_Plugin::factory('Widget_Contents_Post_Edit')->insert来拦截这个方法,并在其中执行自定义代码。 属性(Property): 在 Typecho 的核心类中,某些属性被定义为插入位置。例如,Widget_Contents_Post_Edit 类中的 insert 属性就是一个插入位置。 插件可以通过 Typecho_Plugin::factory('Widget_Contents_Post_Edit')->insert 来拦截这个属性,并在其中执行自定义代码。 13.1示例 假设我们有一个Widget_Contents_Post_Edit类,其中定义了一个insert方法: class Widget_Contents_Post_Edit extends Typecho_Widget { public function insert() { // 插入文章的逻辑 } }在插件中,我们可以通过以下方式拦截这个insert方法: class XXX_Plugin implements Typecho_Plugin_Interface { public static function activate() { Typecho_Plugin::factory('Widget_Contents_Post_Edit')->insert = array('XXX_Plugin', 'publish'); } public static function publish($post) { // 自定义的插入逻辑 } }在这个例子中,XXX_Plugin 插件在 Widget_Contents_Post_Edit 类的 insert 方法执行时,会调用 XXX_Plugin::publish 方法来执行自定义的插入逻辑 十四、常见Hooks整理 1.Widget_Contents_Post_Edit insert:在插入文章时触发。 update:在更新文章时触发。 delete:在删除文章时触发。 finishPublish:在文章发布完成后触发。 2.Widget_Contents_Page_Edit insert:在插入页面时触发。 update:在更新页面时触发。 delete:在删除页面时触发。 finishPublish:在页面发布完成后触发。 3.Widget_Comments_Edit insert:在插入评论时触发。 update:在更新评论时触发。 delete:在删除评论时触发。 finishComment:在评论操作完成后触发。 finishDelete:在评论删除后触发。 4.Widget_Users_Edit insert:在创建用户时触发。 update:在更新用户信息时触发。 delete:在删除用户时触发。 finishCreate:在用户创建完成后触发。 finishDelete:在用户删除后触发。 5.Widget_Metas_Category_Edit insert:在创建分类时触发。 update:在更新分类信息时触发。 delete:在删除分类时触发。 finishCreate:在分类创建完成后触发。 6.Widget_Metas_Tag_Edit insert:在创建标签时触发。 update:在更新标签信息时触发。 delete:在删除标签时触发。 finishCreate:在标签创建完成后触发。 7.Widget_Feedback comment:在用户提交评论时触发。 trackback:在接收Trackback时触发。 8.Widget_Register register:在用户注册时触发。 9.Widget_Login loginSucceed:在用户登录成功后触发。 loginFail:在用户登录失败后触发。 10.Widget_Archive beforeRender:在渲染文章内容之前触发。 afterRender:在渲染文章内容之后触发。 beforeOutput:在输出文章内容之前触发。 afterOutput:在输出文章内容之后触发。 handleInit:在 Archive Widget 初始化时触发。 select:在构建内容查询时触发。 11.Widget_Comments beforeRender:在渲染评论列表之前触发。 afterRender:在渲染评论列表之后触发。 12.Widget_Abstract_Contents contentEx:在获取文章完整内容时触发。 excerptEx:在获取文章摘要内容时触发。 filter:在获取内容列表时触发。 13.Widget_Abstract_Comments contentEx:在获取评论内容时触发。 excerptEx:在获取评论摘要时触发。 filter:在获取评论列表时触发。 14.Widget_Abstract_Metas filter:在获取分类或标签列表时触发。 15.Widget_Abstract_Users filter:在获取用户列表时触发。 16.Widget_Abstract_Options filter:在获取系统选项时触发。 17.Widget_Abstract beforeRender:在任何 Widget 渲染之前触发。 afterRender:在任何 Widget 渲染之后触发。 ___construct:在 Widget 初始化时触发。 ___init:在 Widget 初始化完成后触发。 ___execute:在执行 Widget 主逻辑时触发。 18.Typecho_Widget widget:在创建 Widget 实例时触发。 widgetStart:在 Widget 开始执行时触发。 widgetEnd:在 Widget 执行结束时触发。 19.Typecho_Widget_Helper_Form render:在渲染表单之前触发。 20.Typecho_Widget_Helper_Form_Element render:在渲染表单元素之前触发。 21.Typecho_Db query:在执行数据库查询时触发。 fetchAll:在获取查询结果时触发。 22.Typecho_Router router:在路由解析时触发。 dispatch:在路由调度时触发。 23.Typecho_Response redirect:在执行页面重定向时触发。 24.Typecho_Cookie set:在设置 Cookie时触发。 get:在获取 Cookie时触发。 25.Typecho_Feed output:在输出RSS Feed时触发。 26.Typecho init:在系统初始化时触发。 header:在输出页面头部时触发。 footer:在输出页面尾部时触发。 使用方法示例: Typecho_Plugin::factory('Widget_Contents_Post_Edit')->insert = array('YourPlugin_Class', 'yourMethod');说明: 插入位置(Hook Point):即可拦截的方法名。 触发时机:在对应的方法执行时触发,允许插件在该时机执行自定义逻辑。 使用场景:插件可以通过这些 Hook Points 实现对 Typecho 功能的扩展和定制,例如在文章发布后发送通知,在用户登录失败后记录日志等。 注意事项: 确保方法存在:请确保您定义的插件类和方法存在且可被调用,避免出现错误。 性能考虑:插件开发时应注意性能,避免阻塞核心功能的执行。 充分测试:某些 Hook Points 可能仅在特定情况下触发,开发时需充分测试。 通过以上整理,您可以清晰地了解 Typecho 插件开发中可用的所有插入位置,以及它们的调用位置和意义,方便在插件中实现所需的功能。 -
《前方高能》教程来了。。 一、首先:在style.css添加如下代码: /*high起来*/ .btn-link{border-radius:0;color:#428BCA;cursor:pointer;font-weight:normal;}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:rgba(0,0,0,0);box-shadow:none;}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:rgba(0,0,0,0);}.btn-link:hover,.btn-link:focus{background-color:rgba(0,0,0,0);color:#2A6496;text-decoration:none;}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999999;text-decoration:none;}}二、把下面代码保存到hi.css放到主题目录css下(如果没有自己建一个目录) .mw-strobe_light{position:fixed;width:100%;height:100%;top:0;left:0;z-index:100000;background-color:rgba(250,250,250,0.8);display:block;}.mw-harlem_shake_me{transition:all 0.8s ease-in-out;-moz-transition:all 0.8s ease-in-out;-webkit-transition:all 0.8s ease-in-out;-o-transition:all 0.8s ease-in-out;-ms-transition:all 0.8s ease-in-out;animation:spin 1s infinite linear;-moz-animation:spin 1s infinite linear;-webkit-animation:spin 1s infinite linear;-o-animation:spin 1s infinite linear;-ms-animation:spin 1s infinite linear;}.mw-harlem_shake_slow{transition:all 3.2s ease-in-out;-moz-transition:all 3.2s ease-in-out;-webkit-transition:all 3.2s ease-in-out;-o-transition:all 3.2s ease-in-out;-ms-transition:all 3.2s ease-in-out;animation:spin 4s infinite linear;-moz-animation:spin 4s infinite linear;-webkit-animation:spin 4s infinite linear;-o-animation:spin 4s infinite linear;-ms-animation:spin 4s infinite linear;}body{-webkit-backface-visibility:hidden;}.mw-harlem_shake_me{-webkit-animation-duration:.4s;-moz-animation-duration:.4s;-o-animation-duration:.4s;animation-duration:.4s;-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both;}.mw-harlem_shake_slow{-webkit-animation-duration:1.6s;-moz-animation-duration:1.6s;-o-animation-duration:1.6s;animation-duration:1.6s;-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both;}.flash,.mw-strobe_light{-webkit-animation-name:flash;-moz-animation-name:flash;-o-animation-name:flash;animation-name:flash;}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);}20%,40%,60%,80%{-webkit-transform:translateX(10px);}}@-moz-keyframes shake{0%,100%{-moz-transform:translateX(0);}10%,30%,50%,70%,90%{-moz-transform:translateX(-10px);}20%,40%,60%,80%{-moz-transform:translateX(10px);}}@-o-keyframes shake{0%,100%{-o-transform:translateX(0);}10%,30%,50%,70%,90%{-o-transform:translateX(-10px);}20%,40%,60%,80%{-o-transform:translateX(10px);}}@keyframes shake{0%,100%{transform:translateX(0);}10%,30%,50%,70%,90%{transform:translateX(-10px);}20%,40%,60%,80%{transform:translateX(10px);}}.shake,.im_baked{-webkit-animation-name:shake;-moz-animation-name:shake;-o-animation-name:shake;animation-name:shake;}.swing,.im_drunk{-webkit-transform-origin:top center;-moz-transform-origin:top center;-o-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;-moz-animation-name:swing;-o-animation-name:swing;animation-name:swing;}@-webkit-keyframes wobble{0%{-webkit-transform:translateX(0%);}15%{-webkit-transform:translateX(-15%) rotate(-4deg);}30%{-webkit-transform:translateX(12%) rotate(3deg);}45%{-webkit-transform:translateX(-9%) rotate(-2deg);}60%{-webkit-transform:translateX(6%) rotate(2deg);}75%{-webkit-transform:translateX(-3%) rotate(-1deg);}100%{-webkit-transform:translateX(0%);}}@-moz-keyframes wobble{0%{-moz-transform:translateX(0%);}15%{-moz-transform:translateX(-15%) rotate(-5deg);}30%{-moz-transform:translateX(12%) rotate(3deg);}45%{-moz-transform:translateX(-9%) rotate(-3deg);}60%{-moz-transform:translateX(6%) rotate(2deg);}75%{-moz-transform:translateX(-3%) rotate(-1deg);}100%{-moz-transform:translateX(0%);}}@-o-keyframes wobble{0%{-o-transform:translateX(0%);}15%{-o-transform:translateX(-15%) rotate(-5deg);}30%{-o-transform:translateX(12%) rotate(3deg);}45%{-o-transform:translateX(-9%) rotate(-3deg);}60%{-o-transform:translateX(6%) rotate(2deg);}75%{-o-transform:translateX(-3%) rotate(-1deg);}100%{-o-transform:translateX(0%);}}@keyframes wobble{0%{transform:translateX(0%);}` 15%{transform:translateX(-15%) rotate(-5deg);}30%{transform:translateX(12%) rotate(3deg);}45%{transform:translateX(-9%) rotate(-3deg);}60%{transform:translateX(6%) rotate(2deg);}75%{transform:translateX(-3%) rotate(-1deg);}100%{transform:translateX(0%);}}.wobble,.im_first{-webkit-animation-name:wobble;-moz-animation-name:wobble;-o-animation-name:wobble;animation-name:wobble;}@-webkit-keyframes pulse{0%{-webkit-transform:scale(1);}50%{-webkit-transform:scale(1.1);}100%{-webkit-transform:scale(1);}}@-moz-keyframes pulse{0%{-moz-transform:scale(1);}50%{-moz-transform:scale(1.1);}100%{-moz-transform:scale(1);}}@-o-keyframes pulse{0%{-o-transform:scale(1);}50%{-o-transform:scale(1.1);}100%{-o-transform:scale(1);}}@keyframes pulse{0%{transform:scale(1);}50%{transform:scale(1.1);}100%{transform:scale(1);}}.pulse,.im_blown{-webkit-animation-name:pulse;-moz-animation-name:pulse;-o-animation-name:pulse;animation-name:pulse;}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.3);}50%{opacity:1;-webkit-transform:scale(1.05);}70%{-webkit-transform:scale(.9);}100%{-webkit-transform:scale(1);}}@-moz-keyframes bounceIn{0%{opacity:0;-moz-transform:scale(.3);}50%{opacity:1;-moz-transform:scale(1.05);}70%{-moz-transform:scale(.9);}100%{-moz-transform:scale(1);}}@-o-keyframes bounceIn{0%{opacity:0;-o-transform:scale(.3);}50%{opacity:1;-o-transform:scale(1.05);}70%{-o-transform:scale(.9);}100%{-o-transform:scale(1);}}@keyframes bounceIn{0%{opacity:0;transform:scale(.3);}50%{opacity:1;transform:scale(1.05);}70%{transform:scale(.9);}100%{transform:scale(1);}}.bounceIn,.im_trippin{-webkit-animation-name:bounceIn;-moz-animation-name:bounceIn;-o-animation-name:bounceIn;animation-name:bounceIn;}三、把下面代码复制到js/hi.js(如果没有目录自己建一个|注意代码中mp3和css路径) function hig() { (function() { function c() { var e = document.createElement("link"); e.setAttribute("type", "text/css"); e.setAttribute("rel", "stylesheet"); e.setAttribute("href", f); e.setAttribute("class", l); document.body.appendChild(e) } function h() { var e = document.getElementsByClassName(l); for (var t = 0; t < e.length; t++) { document.body.removeChild(e[t]) } } function p() { var e = document.createElement("div"); e.setAttribute("class", a); document.body.appendChild(e); setTimeout(function() { document.body.removeChild(e) }, 100) } function d(e) { return { height: e.offsetHeight, width: e.offsetWidth } } function v(i) { var s = d(i); return s.height > e && s.height < n && s.width > t && s.width < r } function m(e) { var t = e; var n = 0; while ( !! t) { n += t.offsetTop; t = t.offsetParent } return n } function g() { var e = document.documentElement; if ( !! window.innerWidth) { return window.innerHeight } else if (e && !isNaN(e.clientHeight)) { return e.clientHeight } return 0 } function y() { if (window.pageYOffset) { return window.pageYOffset } return Math.max(document.documentElement.scrollTop, document.body.scrollTop) } function E(e) { var t = m(e); return t >= w && t <= b + w } function S() { var e = document.createElement("audio"); e.setAttribute("class", l); e.src = i; e.loop = false; e.addEventListener("canplay", function() { setTimeout(function() { x(k) }, 500); setTimeout(function() { N(); p(); for (var e = 0; e < O.length; e++) { T(O[e]) } }, 15500) }, true); e.addEventListener("ended", function() { N(); h() }, true); e.innerHTML = " <p>If you are reading this, it is because your browser does not support the audio element. We recommend that you get a new browser.</p> <p>"; document.body.appendChild(e); e.play() } function x(e) { e.className += " " + s + " " + o } function T(e) { e.className += " " + s + " " + u[Math.floor(Math.random() * u.length)] } function N() { var e = document.getElementsByClassName(s); var t = new RegExp("\\b" + s + "\\b"); for (var n = 0; n < e.length;) { e[n].className = e[n].className.replace(t, "") } } var e = 1; var t = 1; var n = 1100; var r = 1100; var i = "http://7j1wr2.com1.z0.glb.clouddn.com/high.mp3"; var s = "mw-harlem_shake_me"; var o = "im_first"; var u = ["im_drunk", "im_baked", "im_trippin", "im_blown"]; var a = "mw-strobe_light"; var f = "https://cdn.nobb.cc/hi/hi.css"; var l = "mw_added_css"; var b = g(); var w = y(); var C = document.getElementsByTagName("*"); var k = null; for (var L = 0; L < C.length; L++) { var A = C[L]; if (v(A)) { if (E(A)) { k = A; break } } } if (A === null) { console.warn("Could not find a node of the right size. Please try a different page."); return } c(); S(); var O = []; for (var L = 0; L < C.length; L++) { var A = C[L]; if (v(A)) { O.push(A) } } })() }四、把下面代码加在主题footer.php里 <script src="/js/hi.js"></script> 五、主页加个按钮调用他 <button type="button" class="btn btn-link" onclick="hig();">前方高能</button> 六、演示 点我开启高能 文件打包下载: 下载地址 下载地址:http://pan.baidu.com/s/1i5HMdN3 提取码:鸡8 -
无限弹窗 首先呢,是必不可少的css样式: .tc_div{background: #fff;border: 1px solid #cdcdcd;width: 200px;border-radius: 5px;box-shadow: 0px 2px 10px #CECACA;position: absolute;} .tc_div h3{background: #E4E4E4;font:bold 15px Arial,Microsoft Yahei;padding: 4px 8px;margin: 0;border-bottom: 1px solid #cdcdcd;border-radius: 5px 5px 0 0;} .tc_div h3 b{float: right;cursor: pointer;} .tc_div p{padding: 6px 8px;}接着是超文本标记语言HTML代码: 我是无良弹窗君 ( *・ω・)✄ <a id="tc_click" style="text-decoration: underline;" href="###"> 敢戳我?分分钟弹死你!</a>最后,最重要的javascript代码来了: <script>// <![CDATA[ /* div弹出层 */ $(document).ready(function() { function doing(Min, Max, Time, Pl, Pt) { /* Min 最少弹出数 Max 最大弹出数 Time 延迟时间 Pl 距离左侧最大百分比 Pt 距离顶部最大百分比 */ if (isNaN(Min) || isNaN(Max) || isNaN(Time) || isNaN(Pl) || isNaN(Pt)) return false; /* 判断输入的是否是数字 */ run = setInterval(function() { if ((Min > Max - 1) && (Max != 0)) clearInterval(run); /* 如果超过最大弹出数则停止 Max为0则无限弹出 */ pl = parseInt(Math.random() * Pl + 1); /* 随机 1~Pl */ pt = parseInt(Math.random() * Pt + 1); /* 随机 1~Pt */ tc_div = ' <div id="tc_div_' + Min + '" class="tc_div"> <h3>小弹窗 No.' + Min + ' <b class="close">×</b></h3> 我是第' + Min + '个小弹窗 </div> '; $(".tc_main").append(tc_div); $("#tc_div_" + Min).css({left: pl + "%",top: pt + "%", "z-index": "100"}); Min++; /* 自增 */ }, Time); } /* 浏览器弹窗 */ function RunAlert() { var i, o, x, z = 10; /* z 弹出次数 */ if (confirm("(●′ω`●) 分分钟弹死你,你信不信?")) { /* 信则弹10*10*10次 不信再说 */ for (i = 1; i <= z; i++) { alert("(= ̄ω ̄=) 霸气第" + i + "弹"); for (o = 1; o <= z; o++) { alert("(= ̄ω ̄=) 霸气第" + i + "弹 \n(。・`ω´・) 骚气第" + o + "弹"); for (x = 1; x <= z; x++) { alert("(= ̄ω ̄=) 霸气第" + i + "弹 \n(。・`ω´・) 骚气第" + o + "弹 \n( ̄へ ̄) 合体第" + x + "弹"); } } } } else { alert("╮( ̄⊿ ̄\")╭ 切,量你也没这个胆子!"); if (confirm("(ง •̀ω•́)ง 试试新玩法?")) { /* 询问是否换个花样 */ $(".tc_main").empty(); doing(1, 0, 100, 85, 88); /* 每100毫秒弹一次 弹到屎 */ } else { alert("(′◔◞౪◟◔) 原来是个胆小鬼!一边玩去!"); return false; } } } $("#tc_click").click(function() { /* 敢点就敢弹 */ RunAlert(); }); $(".tc_main").click(function(e) { var id = e.target.offsetParent.id; $("#" + id).css("z-index", "+=1"); /* 堆叠层数+1 */ if (e.target.className == "close") { $("#" + id).remove(); /* 如果手速快 每个弹窗都可以关掉 */ } }) }) // ]]></script> -
分享两个短链算法 1、Hash,与运算,映射,位移 MD5来Hash;32位分成四份进行与运算,每份保留30位,这30位分成6段, 每5个一组,算出其整数值,然后映射到准备的62个字符中, 依次进行获得一个6位的短链接地址。 <?php function shorturl($longurl) { //hash私钥(被改进部分) //$shorturlkey = '2rcwzfsefw'; //生成随机字串符(ASCII)(改进部分) //$shorturlkey = ''; //for ($i=0; $i <= 15; $i++) { // $shorturlkey .= chr(mt_rand(33,63)); // $shorturlkey .= chr(mt_rand(64,126)); //} //映射字符(被改进部分) $base62 = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'); //对映射字符乱序(改进部分) //shuffle($base62); // 利用md5算法方式生成hash值 //$urlhex = hash('md5', $shorturlkey.$longurl); $urlhex = md5($shorturlkey.$longurl); //计算hash后的长度 $urlhexlen = strlen($urlhex); //长度除以8 $subHexLen = $urlhexlen / 8 ; $output = array(); //处理过程 for ($i = 0; $i < $subHexLen; $i++) { // 将这32位分成四份,每一份8个字符,将其视作16进制串与0x3fffffff(30位1)与操作 $subHex = substr($urlhex, $i*8, 8); $idx = 0x3FFFFFFF & (1 * ('0x' . $subHex)); $out = ''; // 这30位分成6段, 每5个一组,算出其整数值,然后映射到62个字符 for ($j = 0; $j < 6; $j++) { $val = 0x0000003D & $idx; $out .= $base62[$val]; $idx = $idx >> 5; } $output[$i] = $out; } //输出生成的四个当中的随机一个(改进部分) //return $output[mt_rand(0,3)]; //(被改进部分) return $output; } ?>不足 经过实际测试(每次生成5K),原始代码重复率很大,一开始可能只有0.000x%,到后来可能上升到0x%。。。 改进 对映射的字符进行随机排位,最后输出的时候只随机输出4个当中的一个,碰撞几率同下 2、纯随机 <?php function shorturl_rand(){ //循环随机,如果要修改位数,直接修改循环条件中的$i小于(n-1)即可 for ($i=0,$b=''; $i <5 ; $i++) { //随机当前位为数字还是小写字母以及大写字母 $a = mt_rand(0,2); //选择器 switch ($a) { case 0: //随机数字 $b .= chr(mt_rand(48,57)); break; case 1: //随机小写字母 $b .= chr(mt_rand(97,122)); break; case 2: //随机大写字母 $b .= chr(mt_rand(65,90)); break; break; default: break; } } return $b ; } ?>纯随机,碰撞几率最低,性能消耗可能是同类中最低。 -
使用 Google API 生成二维码 Google API 可以非常方便的调用,下边的链接是一个示例: [btnheart href="http://chart.apis.google.com/chart?cht=qr&chs=150x150&chld=L|2&chl=https://nobb.cc" target="_blank"]我是示例[/btnheart] 参数解释: 1、http://chart.apis.google.com/chart? 调用Google API 2、cht=qr 选择生成类型为 qr 码。 3、chs=150×150 设置二维码图片大小。 4、chld=L|4 L表示默认纠错水平;4表示二维码图片的留白大小,留白的大小也是计算在二维码图片大小内的,可选值为 1~4 的整数。 5、chl=https://nobb.cc为二维码内容。 一般 WordPress 文章页可以使用下边的代码调用二维码,具体自己调节参数。 <img src="http://chart.apis.google.com/chart?cht=qr&chs=150x150&chld=L|2&chl=<?php the_permalink(); ?>" class="qrcode pic" width="150" height="150" alt="qrcode" />由于 Google 服务器对国内不太稳定,所以我们可以把二维码图片缓存到本地来解决这一缺陷。 首先将下边的代码扔到当前主题的 functions.php 的最后一个 ?> 前。 /* *Bing - function - 二维码配置 *Form:www.bgbk.org */ //二维码缓存 function Bing_qr($url,$path,$qrpic){ set_time_limit (10); $destination_folder = $path?$path.'/':''; $localname = $destination_folder .$qrpic; $file = fopen ($url, "rb"); if($file){ $newf = fopen ($localname, "wb"); if($newf) while(!feof($file)){ fwrite( $newf, fread($file, 1024 * 2 ), 1024 * 2 ); } } if($file){ fclose($file); } if($newf){ fclose($newf); } } //生成二维码地址 function Bing_echo_qr($imgsize = 150,$echo = true){ $cache = false; $cache = true; if(is_single() || is_page()) $imgname = get_the_id(); elseif (is_home() || is_front_page()) $imgname = 'home'; elseif(is_category()) $imgname = 'cat-'.get_query_var('cat'); elseif(is_tag()) $imgname = 'tag-'.get_query_var('tag_id'); if(!is_home()) $permalink = get_permalink(); else $permalink = get_option('home'); if($cache){ $localqr = ABSPATH .'qrcode/'.$imgname.'.jpg'; if(!file_exists($localqr)){ Bing_qr("http://chart.googleapis.com/chart?cht=qr&chs=".$imgsize."x".$imgsize."&choe=UTF-8&chld=L|0&chl=".$permalink ,"qrcode", $imgname.".jpg"); } $main = get_home_url('').'/qrcode/'.$imgname.'.jpg'; } else $main = "http://chart.googleapis.com/chart?cht=qr&chs=".$imgsize."x".$imgsize."&choe=UTF-8&chld=L|0&chl=".$permalink; if($echo) echo $main; else return $main; } //输出二维码 function Bing_echo_qrcode($imgsize = 150){ echo '<img src="'.Bing_echo_qr($imgsize,false).'" class="qrcode" width="'.$imgsize.'" height="'.$imgsize.'" alt="qrcode" />'; }然后在需要调用二维码的地方使用下边的函数就行了: <?php if(function_exists('Bing_echo_qrcode')&&function_exists('Bing_echo_qr')&&function_exists('Bing_qr')) Bing_echo_qrcode(150);?>其中的 150 为二维码大小,可以自己修改。 如果想关闭二维码缓存只需要将第一段代码的 30 行 $cache = true; 注释掉即可。