WordPress 插件开发教程 – Part-3 – 钩子( hooks )

钩子是 WordPress 的精髓。他们允许插件开发人员钩进 WordPress 工作流程内部来改变它的工作,而不用直接修改核心代码。这就使得用户可以方便的升级到 WordPress 的新版本而不需要修改一行代码。

如果一个开发人员修改了核心代码,这些改动在 WordPress 下一次升级的时候就会消失。升级会覆盖这些改动。使用钩子让你能够在核心以外的目录中单独开发插件,这就在升级时保证了插件代码的安全。

没有钩子,插件就没办法改变 WordPress 的功能了。本节介绍的钩子系统会贯穿整个教程,同时也会在几乎每一个插件的开发中用到。在你学会了钩子的用法后,你就会明白为什么 WordPress 这个平台这么强大,并有上千个插件供几百万用户使用了。

WordPress 主要有两种类型的钩子:动作钩子和过滤器钩子(action hooks and filter hooks )。第一个使得你可以在一个特定时刻上执行一个函数,第二个使得你可以操作通过钩子的输出。

钩子不是仅仅针对插件的。WordPress 内部也使用钩子。如果你浏览核心代码,你就能见到很多 WordPress 自己钩自己的例子了。

动作钩子 ( actions )

动作钩子让你可以在 WordPress 加载过程中或者当某个事件发生的特定时刻触发一个函数。例如:你可能希望当 WordPress 第一次加载一个页面或者保存一篇文章时执行一个函数。

你需要理解 do_action() 函数。当钩进 WordPress 中时,你的插件不会直接调用这个函数;但是你的插件几乎都会间接的使用它。

  • $tag — 动作钩子的名称
  • $arg — 传递给已注册的动作的值。它看起来像一个单独的参数,但通常都不是这样的。动作钩子可以传递任何个数的参数,或者根本不传参数。对特殊的钩子,你需要查看 WordPress 的源码,因为参数个数在每个钩子的基础改变。

    下面是一个具有多参数的动作钩子的例子:

    下面看看一个叫做 wp_head 的钩子是怎么出现在 WordPress 中的。这个钩子出现在前台的 里面。 WordPress 和插件经常用这个钩子来添加 meta 信息,样式表,和 js 脚本。

    当这段代码在 WordPress 中执行时,它会寻找任何为 wp_head 动作钩子注册的动作。然后按照特殊顺序执行它们。如你所见,它名叫 wp_head 但是没有传递额外的参数。动作钩子通常都这样。下面是有两个额外参数的动作钩子的例子:

    这个 save_post 的钩子传递两个参数,一个 $post_ID,一个 $post。

    什么是动作?

    从技术上讲,一个动作就是一个 PHP 函数。一个函数要成为一个动作,它需要被注册成一个动作钩子。在上面的部分可以看到什么是动作钩子,但是动作钩子要用作任何目的,需要有个动作为它们注册。这就是插件的来源。你开发的自定义的函数(动作)当动作钩子出发之后就可以执行一个特定任务了。要实现这个,就要使用 add_action() 函数。

    • $tag – 你的函数执行时代动作钩子的名称。
    • $function – WordPress 要调用的函数名。
    • $priority – 一个表示动作调用顺序的整数,默认是10。数字越小,这个函数越早被调用。
    • $accepted_args – 动作钩子要传递给你的函数的参数个数。默认只有一个参数。

    动作钩子并不局限于单个动作。你的插件可以将多个函数添加到一个动作钩子上。其他插件,甚至是 WordPress 核心,经常将多个函数添加到同一个钩子上。

    现在是使用动作钩子的时候了。一个常见的动作钩子是 wp_footer 。它提供给前端用户的 WordPress 模板使用。通常它刚好在前调用。在下面的例子中,将要为 wp_footer 注册一个动作并添加一条自定义信息到 footer。

    WordPress 架设。;
    }
    ?>

    仔细看看上面的代码中如何使用 add_action() 函数的。

    第一个参数是钩子的名字( wp_footer )。第二个参数是要回调的函数 ( boj_example_footer_message )。第三个参数是优先级 ( 100 )。这个函数比起其他钩到 wp_footer 中的函数,会在比较靠后的次序执行。如果设置成1,就较先执行。

    要说明,钩子可能会因为许多原因在 WordPress 执行过程中多次触发。任何添加到这个钩子中的动作每当钩子触发时都会执行一次。

    动作钩子函数

    你已经知道了最基本的两个动作钩子函数怎么使用;do_action() 和 add_action()。WordPress 还有其他类型的与动作钩子相关的函数用于插件开发。

    do_action_ref_array() 函数和 do_action() 函数完成同样的工作,只不过参数传递的方式不同。它并不传递通过附加参数的值来确定的多个参数,而是传递一个包含参数的数组。这个参数数组也是一个必须的参数。这个函数的目的是通过引用传递一个对象给添加到特定钩子的动作(函数)。这意味着这个函数可以不用返回就改变对象本身。
    • $tag – 动作钩子的名字。
    • $args – 要传递给注册到这个钩子的函数的参数的数组。通常,这是一个动作可以改变的对象。

    下面看一个 WordPress 如何调用 do_action_ref_array() 的实例。下面的代码展示了 pre_get_posts 动作钩子。WordPress 在从数据库取得 posts 之前执行这个钩子,使得插件可以改变查询 posts 的方式。

    第一个参数 pre_get_posts 是钩子的名字。第二个参数是从数据库中查询 posts 的参数的数组。这个钩子使你可以执行基于那个参数数组的代码。

    假如你想安装随机的顺序来得到首页的 blog,而不是默认的通过发布时间来得到。你就需要注册一个动作到这个钩子,并改变排序顺序。

     is_home &&empty($query-> query_vars['suppress_filters']))
            $query-> set('rderby','rand');
    }
    ?>

    remove_action() 可以删除先前添加到一个钩子的动作。代表性的,你可以删除 WordPress 默认添加的动作。要删除一个动作,这个动作必须已经用 add_action() 函数添加了。如果你在动作注册之前执行 remove_action(),那么动作并不会被从钩子中删除。

    如果动作被成功删除,则函数返回 true,否则返回 false。

    参数类似于 do_action()。要成功的从一个钩子中删除一个动作, $tag, $function_to_remove, 和 $priority 必须完全的符合 do_action() 中使用的参数。否则动作不会被溢出,同时 remove_action() 返回 flase。

    我们看一个叫做 rel_canonical 的 WordPress 默认动作。这个动作在 和 元素之间添加一个 canonical 链接。

    要删除这个动作,就要使用 remove_action() 函数。你需要定义 $tag 和 $function_to_rmove 参数。这里你不用添加 $priority 因为先前定义动作的时候没有明确指定优先级。

    WordPress、plugin 或者 theme 添加的任何动作都可以在插件中删除。通常只删除 WordPress 添加的动作。许多默认的动作都定义在 wp-includes/default-filters.php 文件中。通过浏览这个文件你就会明白 WordPress 是如何使用动作钩子的。

    remove_all_actions

    在有些插件中,可能需要删除所有特定 tag 或者 特定 tag + 特定优先级的所有钩子。使用 remove_all_actions() 可以一次删除所有符合条件的动作。

    $priority 参数是可选的,默认是 false。如果你设置了这个参数,那么只有这个优先级的动作会被删除。下面的例子从 wp_head 动作钩子中删除不管任何优先级的动作。

    在使用这个函数的时候必须要小心。其他 plugin 或者 theme 可能添加了你不知道动作。这就可能破坏插件应有的功能。通常应该保持你的代码尽可能的特殊。在大多数情况下,你应该使用 remove_action() 函数来代替。

    有的时候需要确定一个钩子是否包含一些动作,或者一个特定的动作是否已经添加到了钩子里面。has_action() 提供了这些功能。

    has_action() 函数的返回值是 Boolean 或者 一个整型值。如果 $function_to_check 参数为空,那么如果有动作已经添加到了钩子中就返回 true,反之,返回 false。而如果 $function_to_check 设置了,而且这个函数已经添加到了钩子里面,则返回该动作的优先级,否则返回 false。

    下面的例子中,根据 wp_footer 动作钩子中是否有注册的动作来确定显示的信息。

     footer 中已经注册有动作了。

    '; else echo'

    footer 中还没有注册动作。

    '; ?>

    下面看一个 WordPress 核心添加到 wp_footer 中的动作。wp_print_footer_script() 默认注册给这个钩子。

    did_action() 使你的插件可以检查一个动作钩子是否已经被执行,或者记录执行的次数。这也意味着这一次页面的加载过程中有些动作被执行了多次。

    这个参数返回动作已经执行的次数,如果还未执行,返回 false。这个函数的一般用途是判断一个动作钩子是否已经被触发,并执行基于 did_action() 的返回值的代码。

    下面的例子中,如果 plugins_loaded 动作钩子已经被触发,就定义一个 PHP 常量。

    register_activation_hook 和 register_deactivation_hook

    在第二章中已经介绍了这两个函数。

    常用的动作钩子

    WordPress 有许多动作钩子,有一些是很常用的。

    plugins_loaded

    对插件开发者来说,plugins_loaded 动作钩子也许是最重要的动作钩子了。它在大多数 WordPress 文件加载完成之后,并在pluggable 函数和 WordPress 开始执行任何东西之前触发。在大多数的插件中,在这个钩子触发之前,不应该执行其他的代码。plugins_loaded 在所有用户启用的插件都被 WordPress 加载之后执行。这也是在加载过程中插件开发这最早能用到的钩子。

    WordPress 的插件应该在这个钩子中执行安装。其他动作也应该添加到这个钩子的回调函数中。

    下面的例子中,使用前面部分创建的 boj_example_footer_message 动作。要把它添加到钩到 plugins_loaded 钩子中的安装动作中,而不是单独调用它。

    WordPress 架设。;
    }
    ?>

    创建一个安装函数并把它钩到 plugins_loaded 中。这样做就可以确保不会由于特定的 WordPress 函数还没有加载而触发错误。

    init

    init 钩子在大多数的 WordPress 都建立之后。WordPress 同样添加许多内部的功能到这个钩子中,例如 post types 和 taxonomies 的厨厕以及默认 widgets 的初始化。

    因为这时几乎 WordPress 中的所有内容都就绪了,当 WordPress 的所有信息都可用时,你的插件使用这个钩子差不多可以做任何需要的事情了。

    下面的例子中,为用户添加了给 pages 写摘要的功能。这应该在 init 中执行,因为 “page” post type 在这时使用 add_post_type_support() 函数来创建。( 详见 Part-11, “扩展 posts”)

    admin_menu

    admin_menu 钩子在管理员页面加载的时候调用。无论何时你的插件直接在管理页面下工作,你都要用这个钩子来执行你的代码。

    下面的例子添加了一个内容是 BOJ Settings 的 sub-menu 项到 WordPress 管理页面的设置菜单。(详见:Part-7,”插件设置”)

    template_redirect

    template_redirect 动作钩子很有用,因为它是 WordPress 知道用户正在浏览的页面的关键。它在特定的页面选择 theme template 之前执行。在只在网站的前端触发,并不在管理员页面触发。

    当你需要为特定的页面加载代码的时候,这个钩子很有用。

    下面的例子中,仅仅为 singular post 加载一个样式表文件。

    wp_head

    在网站的前端,WordPress 的模板调用 wp_head() 函数,会触发 wp_head 钩子。插件使用这个钩子在 和 标签之间添加 HTML。

    下面的例子中在前端添加一个 meta description。

    ';
    }
    ?>

    有些插件错误的使用了 wp_head 动作钩子来添加 JavaScript 代码,实际上应该使用 wp_enqueue_script() 函数的。( 详见:Part-12,”JavaScript 和 AJAX “)。唯一一种使用这个钩子来添加 JavaScript 的情形是当 JavaScript 代码不在一个单独的文件中时。

    过滤器 Filters

    过滤器钩子和动作钩子有很大的区别。它让你可以控制代码的输出。动作钩子是让你插入代码,而过滤器钩子让你重写 WordPress 传递给钩子的代码。你的函数会对输出进行”过滤”。

    要掌握过滤器钩子的概念,必须首先明白 WordPress 的 apply_filters() 函数是如何工作的。

    • $tag – 过滤器钩子的名字。
    • $value – 传递给任何添加到这个钩子的过滤器的参数。这个函数可以添加任意个额外的 $value 参数传递给过滤器。

    注意:在写一个过滤器的时候 $value 必须返回给 WordPress。

    下面是 WordPress 核心的一个过滤器钩子的例子:

    这个例子中,template_include 是一个过滤器钩子的名字,$template 是一个可以通过注册到这个过滤器钩子的过滤器改变的文件名。

    什么是过滤器?

    一个过滤器是一个注册到过滤器钩子的函数。这个函数最少接受一个参数并在执行完代码后返回那个参数。没有过滤器的过滤器钩子没有任何作用。插件开发者可以通过过滤器钩子改变不同的变量 – 从字符串到多位数组。

    当一个过滤器钩子被 apply_filters() 函数调用时,所有注册到这个钩子的过滤器都会被执行。要添加一个过滤器,使用 add_filter() 函数。

    和动作钩子添加动作类似。$accepted_args 是过滤器函数 $function 接受的参数个数,默认是1。你的函数必须至少接受一个参数并返回。

    可以给一个过滤器钩子添加多个过滤器。同样其他 WordPress 插件也可以给这个钩子添加过滤器。过滤器钩子并不限制给一个钩子。注意:因为每个过滤器都必须返回一个值供其他过滤器使用。如果你的函数没有返回值,那就可能会破坏整个 WordPress 或者其他的插件。

    下面看看 wp_title 过滤器钩子,它是负责页面的 元素的过滤器钩子。</p> <div> <div id="highlighter_430273" class="syntaxhighlighter php"> <pre><code class="language-php"><?php apply_filters( 'wp_title', $title,$sep,$seplocation); ?></code></pre> </div> </div> <ul> <li>wp_title – 钩子名。</li> <li>$title – 一个字符串,要过滤并返回给 WordPress 的值。</li> <li>$sep – 说明 <title> 元素之间的分隔符是什么。</li> <li>$seplocation – 分隔符的位置。下一个例子中要用到。</li> </ul><p>现在写一个函数来过滤 $title 的输出 – 在页面的 title 后面附加站点的名字:</p> <div> <div id="highlighter_949063" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_filter( 'wp_title', 'boj_add_site_name_to_title', 10, 2 ); function boj_add_site_name_to_title( $title,$seq) { /* 得到网站名称 */ $name = get_bloginfo('name'); /* 附加到 $title 变量。 */ $title.=$sqp.' '.$name; /* 返回 $title */ return$title; } ?></code></pre> </div> </div> <p>boj_add_site_name_to_title() 函数修改 $title 参数并返回给 WordPress。$sep 参数在函数中使用,但没有返回。</p> <h3>过滤器钩子函数</h3> <p>除了前面提到的 apply_filters() 和 add_filter() 函数,WordPress 还提供其他的操作过滤器钩子的函数。</p> <h4>apply_filters_ref_array</h4> <p>类似于动作钩子里面的 do_action_ref_array() 函数。</p> <div> <div id="highlighter_68552" class="syntaxhighlighter php"> <pre><code class="language-php"><?php apply_filters_ref_array($tag,$args); ?></code></pre> </div> </div> <p>假设你要执行一个一般的 WordPress 没有的复杂的数据库查询来加载首页的 posts。WordPress 提供了一个叫做 posts_results 的过滤器钩子使得你可以改变它。下面是 WordPress 核心中的代码:</p> <div> <div id="highlighter_463557" class="syntaxhighlighter php"> <pre><code class="language-php"><?php $this -> posts = apply_filters_ref_array( 'posts_results',array($this-> posts, &$this) ); ?></code></pre> </div> </div> <p>这个过滤器钩子向所有注册到它的过滤器传递一个 post 对象的数组。下面的例子,你完全重写这个 post 对象的数组并用自定义的内容代替。默认情况下,WordPress 查询 post 类型的 posts。下面改成查询 page 类型的 psots 并显示在首页。</p> <p>这段代码使用了 wpdb 类,在 part-6 “插件安全” 中将详细介绍。</p> <div> <div id="highlighter_606576" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_filter( 'posts_result', 'boj_custom_home_page_posts'); function boj_cumstom_home_page_posts( $result ) { global$wpdb,$wp_query; /* 检查是否在首页 */ if( is_home() ) { /* 每页的 post 个数 */ $per_page= get_option('posts_per_page'); /* 得到当前页 */ $paged= get_query_var('paged'); /* 设置 $page 变量 */ $page= ( ( 0 ==$paged|| 1 ==$paged ) ? 1 : absint($paged ) ); /* 设置偏移的 posts 的个数 */ $offset= ($page- 1 ) * $per_page.','; /* 通过 $offset 和 要显示的 posts 数量来设置 limit */ $limits='LIMIT'.$offset.$per_page; /* 从数据库查询结果 */ $result=$wpdb-> get_results(" SELECT SQL_CALC_FOUND_ROWS$wpdb-> posts. * FROM$wpdb-> posts WHERE 1 = 1 AND post_type ='page' AND post_status ='publish' ORDER BY post_title ASC$limits" ); } return$result; } ?></code></pre> </div> </div> <h4>remove_filter</h4> <div> <div id="highlighter_406898" class="syntaxhighlighter php"> <pre><code class="language-php"><?php remove_filter( $tag, $function_to_remove,$priority,$accepted_args); ?></code></pre> </div> </div> <p>这和前面的 remove_action 类似。</p> <p>下面看看 WordPress 定义在 wp-includes/default-filters.php 页面中的默认的过滤器。其中一个有意思的过滤器叫做 wpautop(),它将双换行转换成 HTML 的 <p> </p>。这也就是我们在 HTML 发布内容时,直接回车便可在最终前端显示的时候换行的原因。它在核心代码中的几个钩子中都执行。下面是其中一个实例:</p> <div> <div id="highlighter_866470" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_filter( 'the_content', 'wpautop'); ?></code></pre> </div> </div> <p>这将 wpautop() 过滤器应用到 post 的内容中,把每个换行都转换成段落( <p> )。但是也许有的客户不希望他的内容自动变成段落。那么你就可以使用 remove_filter() 函数从 the_content 钩子中删除这个过滤器。</p> <div> <div id="highlighter_287231" class="syntaxhighlighter php"> <pre><code class="language-php"><?php remove_filter( 'the_content', 'wpautop'); ?></code></pre> </div> </div> <p>因为在 add_filter 的时候没有定义优先级,所以这里也不需要。</p> <h4>remove_all_filters</h4> <p>和前面的remove_all_actions类似。</p> <div> <div id="highlighter_206690" class="syntaxhighlighter php"> <pre><code class="language-php"><?php remove_all_filters($tag,$priority); ?></code></pre> </div> </div> <p>has_filter</p> <p>和前面的 has_action 类似。</p> <h4>current_filter</h4> <p>同样类似于 did_action。不过它不仅仅对过滤器钩子有效,同样对动作钩子也有效,所以它返回的是当前的 action 或者 filter 钩子。这个函数在你对多个钩子使用单个函数,但是需要依赖不同的钩子执行不同的内容的时候非常的有用。例如,客户希望在 post 标题 和内容中限制一些内容,但是这两个限制的minganci的集合是不同的。使用 current_filter() 函数来根据钩子设置不同的minganci表就可以实现用一个函数同时过滤 the_content 和 the_title。使用下面的代码,你可以把minganci替换成**。</p> <div> <div id="highlighter_150391" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_filter( 'the_content', 'boj_replace_unwanted_words'); add_filter( 'the_title', 'boj_replace_unwanted_words'); function boj_replace_unwanted_words( $text ) { /* 如果过滤器钩子是 the_content */ if('the_content'== current_filter() ) $words=array('min','gan','ci'); /* 如果钩子是 the_title */ elseif('the_title'== current_filter() ) $words=array('zhen','de','hen','min','gan'); /* 替换minganci */ $text=str_replace($words,'**',$text); return$text; } ?></code></pre> </div> </div> <h3>快速返回函数</h3> <p>你经常需要写一个函数返回一个常用的值给一个过滤器钩子,例如 true,false,或者一个空数组。你甚至尝试使用 PHP 的 create_function() 函数来快速返回一个值。</p> <p>WordPress 提供几个函数处理这种情况。</p> <p>下面是例子禁用了 user contact 方法 – 在 WordPress 的个人用户管理页面中的一系列 <input>。要禁用这些表单项,你需要返回一个空数组。通常,你必须添加过滤器钩子调用和函数。</p> <div> <div id="highlighter_42043" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_filter( 'user_contactmethods', 'boj_return_empty_array' ); function boj_return_empty_array() { returnarray(); } ?></code></pre> </div> </div> <p>写这样的代码一两次并没什么。但是写一个返回空数组的函数太傻了。WordPress 使之简单化了。因为要禁用这些表单项,你只需要使用 WordPress 的 __return_empty_array() 函数作为过滤器来快速返回一个空数组。如下:</p> <div> <div id="highlighter_874481" class="syntaxhighlighter php"> <pre><code class="language-php">add_filter( 'user_contactmethods', '__return_empty_array' )</code></pre> </div> </div> <p>还有几个类似的快速返回函数:</p> <ul> <li>__return_false</li> <li>__return_true</li> <li>__return_zero</li> </ul><p>如果上面的函数不符合你的要求,你还可以创建自己的快速返回函数。</p> <h3>常用的过滤器钩子</h3> <p>WordPress 上百种过滤去钩子提供给插件开发者。下面介绍一些常用的过滤器钩子。</p> <h4>the_content</h4> <p><span style="color:rgb(255,0,0);font-weight:bold;">the_content 可以说是用的最多的过滤器钩子了。</span>没有内容,一个网站一点用处也没有。内容是一个网站上最重要的东子,插件使用这个钩子为网站添加许多特色。</p> <p>the_content 钩子向所有注册给它的过滤器传递一个 post 的内容。之后由过滤器来控制内容,通常添加一些格式化或者附加而外的一些信息。下面的例子根据 post 分类,当用户阅读一篇 post 时显示一个附加的相关 post 列表到 the_content。</p> <div> <div id="highlighter_85232" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_filter( 'the_content', 'boj_add_related_posts_to_content'); function boj_add_related_posts_to_content( $content) { /* 如果不是单篇文章,直接返回 content */ if( !is_singular('post') ) return$content; /* 得到当前 post 的分类 */ $terms= get_the_terms( get_the_ID(),'category'); /* 循环分类,并将它们的 ID 放到一个数组中 */ $categories=array(); foreach($termsas$term ) $categories[] =$term-> term_id; /* 从数据库查询相同分类的 posts */ $loop=newWP_Query( array( 'cat__in'=>$categories, 'posts_per_page'=> 5, 'post__not_in'=>array( get_the_ID() ), 'orderby'=>'rand' ) ); /* 是否有相关 posts 存在 */ if($loop-> have_posts() ) { /* 开始 ul */ $content.='<ul class="related-posts">'; while($loop-> have_posts() { $loop-> the_post(); /* 添加 post 标题 */ $content.= the_title ( '<li><a href="'.get_permalink().'">', '</a></li>', false ); } /* 结束 ul */ $content.='</ul>'; /* 重置 query */ wp_reset_query(); } /* 返回 content */ $return$content; } ?></code></pre> </div> </div> <h4>the_title</h4> <p>文章的标题几乎和内容一样重要,所以 the_title 也是一个常用的过滤器钩子。你可以使用这个钩子添加信息,或者直接重写。</p> <p>应用给 the_title 钩子的一个有用的过滤器就是去除标题中 HTML 标签的过滤器函数。用户有时会添加一些标签到标题中,这可能会破坏正常的格式。使用下面的代码,你可以过滤掉所有用户可能添加到标签。</p> <div> <div id="highlighter_203692" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_filter( 'the_title', 'boj_strip_tags_from_titles'); function boj_strip_tags_from_title( $title ) { $title=strip_tags($title); $return$title; } ?></code></pre> </div> </div> <h4>同样 comment_text 也很常用。</h4> <p>下面的例子中,检查一条评论是否是网站的注册用户发表的。如果是注册用户,你可以附加一段用户信息的说明( 详见:Part-8,”用户” )</p> <div> <div id="highlighter_265510" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_filter( 'comment_text', 'boj_add_role_to_comment_text'); function boj_add_role_to_comment_text( $text ) { global$comment; /* 检查是否是注册用户 */ if($comment-> user_id > 0 ) { /* 新建一个用户对象 */ $user=newWP_User( $comment-> user_id ); /* 如果用户有一个角色,添加到评论内容中 */ if(is_array($user-> roles ) ) $text.='<p>User Role: '.$user-> roles[0]. '</p>'; } return$text; } ?></code></pre> </div> </div> <h4>template_include</h4> <p>template_include 是其他一些更特殊的过滤器钩子的一类”杂物包”( catchall )过滤器钩子。</p> <ul> <li>front_page_template</li> <li>home_template</li> <li>single_template</li> <li>page_template</li> <li>attachment_template</li> <li>archive_template</li> <li>category_template</li> <li>tag_template</li> <li>author_template</li> <li>date_template</li> <li>search_template</li> <li>404_template</li> <li>index_template</li> </ul><p>它用在 theme template 过滤器后面,当当前页被选中后。WordPress 根据读者当前浏览的页面来选择一个模板。你可以为每一个独立的过滤器钩子添加一个过滤器,也可以在最后使用 template_include 钩子一起过滤他们。</p> <p>比如你想按照你的插件的标准构造一个模板层级结构,而不是使用 WordPress 默认的模板层级。template_include 和上面列表中的钩子可以满足你。</p> <p>下面的例子中,根据分类判断一个 posts 的模板是否存在。默认情况下,WordPress 先检查 single.php,如果不存在,再检查 index.php文件。而你的函数查找一个叫做 single-category-$slug.php ( $slug 是分类的别名 )的文件。所以如果用户有一个叫 art 的分类,同时一个模板的名字叫做 single-category-art.php,那么这个文件会被用来代替 single.php。</p> <div> <div id="highlighter_601391" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_filter( 'single_template', 'boj_single_template' ); function boj_single_template( $template ) { global$wp_query; /* 检查是否在浏览单个 post */ if( is_singular('post') ) { /* 获得 post ID */ $post_id=$wp_query-> get_queried_object_id(); /* 获得 post 的分类 */ $terms= get_the_terms($post_id,'category'); /* 循环分类,添加别名作为文件名的一部分 */ $template=array(); foreach($termsas$term ) $templates[] ="single-category-{$term->slug}.php"; /* 检查模板是否存在 */ $locate= locate_template($templates); /* 如果找到,让它成为新模板 */ if( !empty($locate) ) $template=$locate; } /* 换回模板文件名 */ return$template; } ?></code></pre> </div> </div> <h2>使用一个类中的钩子</h2> <p>前面已经讲了许多通过 PHP 函数来使用动作钩子和过滤器钩子的例子。在类中添加一个方法作为一个动作或者过滤器的时候,格式和 add_action() 和 add_filter() 略微有些不同。</p> <p>一般来说,插件使用函数而不是类中的方法作为动作或者过滤器。但是,可能有些时候使用类更适合,所以你要知道如何类在类中将方法注册到钩子。</p> <p>前面已经提到的注册函数到一个动作钩子的方法:</p> <div> <div id="highlighter_90945" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_action( $tag, $function_to_add); ?></code></pre> </div> </div> <p>当在类中将方法作为 $function_to_add 参数时,你必须把 $function_to_add 变成一个数组,其中 & $this 作为第一个参数,方法名作为第二个参数:</p> <div> <div id="highlighter_177374" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_action( $tag, array( &$this,$method_to_add) ); ?></code></pre> </div> </div> <p>对于过滤器钩子也是一样。一般的将函数添加到一个过滤器钩子类似于:</p> <div> <div id="highlighter_248128" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_filter( $tag, $function_to_add); ?></code></pre> </div> </div> <p>当使用类的方法的时候,要改成:</p> <div> <div id="highlighter_744104" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_filter( $tag, array( &$this,$method_to_add) ); ?></code></pre> </div> </div> <p>下面的例子中,创建了一个类,包含一个构造函数,一个作为动作的方法,和一个作为过滤器的方法。add_filters() 方法检查用户是否在浏览单篇 post。如果是 content() 方法附加最后的修改时间到 post 的内容中。</p> <div> <div id="highlighter_48128" class="syntaxhighlighter php"> <pre><code class="language-php"><?php class BOJ_My_Plugin_Loader { /* 类的构造函数 */ functionBOJ_My_Plugin_Loader() { /* 为 'template_redirect' 钩子添加 'singular_check' 方法 */ add_action('template_redirect',array( & $this,'singular_check') ); } /* 作为动作的方法 */ functionsingular_check() { /* 如果在看单个文章,过滤内容 */ if( is_singular() ) add_filter('the_content',array( & $this,'content') ); } /* 作为过滤器的方法 */ functioncontent($content) { /* 得到 post 的最后修改时间 */ $date= get_the_modified_time( get_option('date_format') ); /* 附加修改时间到 content */ $content.='<p> 最后修改于:'.$date.'</p>'; return$content; } } $boj_myplugin_loader=newBOJ_My_Plugin_Loader(); ?></code></pre> </div> </div> <h2>创建自定义钩子</h2> <p>插件不但可以使用内核的内置钩子,他们也可以创建自定义的钩子供其他插件和模板使用。</p> <p>插件可以使用4个可用函数中的一个来创建自定义钩子。</p> <ul> <li>do_action()</li> <li>do_action_ref_array()</li> <li>apply_filters()</li> <li>apply_filters_ref_array()</li> </ul><p>前两个创建自定义动作钩子,后两个创建自定义过滤器钩子。</p> <h3>创建自定义钩子的优点</h3> <p>自定义钩子使得你的插件更灵活,使其可以被其他插件扩展,让你可以钩到你的整个插件自己的其他执行过程中。</p> <p>使用自定义钩子还可以防止用户直接修改你的插件。这一点的重要性在于,当你更新你的插件时,用户不会失去他们修改的内容。</p> <h3>自定义动作钩子实例</h3> <p>在这个例子中,建立了一个插件安装函数。这个函数定义了一个可以更换的常量。别的插件也可以在这个钩子上执行任何代码。因为你在那一点上提供了钩子。</p> <div> <div id="highlighter_967106" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_action( 'plugins_loaded', 'boj_myplugin_setup' ); function boj_myplugin_setup() { /* 允许动作最先触发 */ do_action('boj_myplugin_setup_pre'); /* 检查 root slug 是否定义 */ if( !defined('BOJ_MYPLUGIN_ROOT_SLUG') ) define('BOJ_MYPLUGIN_ROOT_SLUG','articles'); } ?></code></pre> </div> </div> <p>其他插件或者模板可以钩到 boj_myplugin_setup_pre 来执行任何函数。</p> <p>比如你想把 BOJ_MYPLUGIN_ROOT_SLUG 常量从 ‘articles’ 改为 ‘papers’ ,你可以建立一个动作并添加到这个钩子中:</p> <div> <div id="highlighter_392053" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_action( 'boj_myplugin_setup_pre','boj_define_myplugin_constants'); function boj_define_myplugin_constants() { define('BOJ_MYPLUGIN_ROOT_SLUG','papers'); } ?></code></pre> </div> </div> <h3>自定义过滤器钩子实例</h3> <p>假设有一个函数显示一个具有一个特定阐述的文章列表。你也许希望其他人能够过滤那个参数或者过滤最终结果。</p> <p>下面的例子中,写一个函数根据收到的评论条数列取了前10的文章。这个函数让用户可以在从数据库获取数据前过滤这个参数,并且可以过滤最终输出的 HTML 列表。</p> <div> <div id="highlighter_596421" class="syntaxhighlighter php"> <pre><code class="language-php"><?php function boj_posts_by_comments() { /* 默认参数 */ $args=array( 'post_type'=>'post', 'posts_per_page'=> 10, 'order'=>'DESC', 'oerderby'=>'comment_count' ); /* 应用过滤器 */ $args= apply_filters('boj_posts_by_comments_args',$args); /* 设置输出变量 */ $out=''; /* 由给定的参数从数据库查询文章 */ $loop=newWP_Query( $args ); /* 检查是否返回结果 */ if($loop-> have_posts() ) { $out.='<ul class="posts-by-comments" >'; while($loop-> have_posts() ) { $loop-> the_post(); $out.= the_title('<li>','</li>', false ); } $out.='</ul>'; } $out= apply_filters('boj_posts_by_comments',$out); echo$out; } ?></code></pre> </div> </div> <p>要过滤参数,给 boj_posts_by_comments_args 添加一个过滤器。比如你希望把数量从默认的10变成15,添加下面的过滤器:</p> <div> <div id="highlighter_846216" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_filter( 'boj_posts_by_comments_args','boj_change_posts_by_comments_args'); function boj_change_posts_by_comments_args( $args) { $args['posts_per_page'] = 15; return$args; } ?></code></pre> </div> </div> <p>要过滤最后的 HTML 输出,添加一个过滤器到 boj_posts_by_comments。比如你想把 ul 改成 ol。</p> <div> <div id="highlighter_665735" class="syntaxhighlighter php"> <pre><code class="language-php"><?php add_filter( 'boj_posts_by_comments', 'boj_change_posts_by_comments' ); function boj_change_posts_by_comments( $out ) { $out=str_replace('<ul','<ol',$out); $out=str_replace('</ul>','</ol>',$out); return$out; } ?></code></pre> </div> </div> <h2>上哪找钩子?</h2> <p>要给出 WordPress 中所有钩子的列表几乎是不可能的。前面我们讨论了一些常用的动作和过滤器钩子,这一节仅仅讨论一小部分 WordPress 提供的钩子。</p> <p>WordPress 的新版本会加入新的钩子。最终查看不同版本的内核可以让你找到可以用在插件中的新钩子。</p> <h3>在内核中搜索钩子</h3> <p>作为一个插件开发这,你应该熟悉 WordPress 的内核。寻找钩子能很好的帮助你熟悉 WordPress 内核是如何工作的。没有更好的方法来搞明白 PHP 代码在内核中是如何工作的了。</p> <p>要寻找钩子的一个简单的方法是在编辑器中打开一个 WordPress 文件然后搜索下面的四个词:</p> <ul> <li>do_action</li> <li>do_action_ref_array</li> <li>apply_filters</li> <li>apply_filters_ref_array</li> </ul><p>这四个函数,每一个都创建一个钩子。</p> <h3>变量钩子</h3> <p>在 WordPress 的内核中找钩子的时候,你会遇到变量钩子。通常钩子的名字是一个静态的字符串。但是变量钩子的名字跟着特定的变量而改变。</p> <p>一个很好的例子就是 load-$pagenow 动作钩子。变量 $pagenow 根据 WordPress 中当前浏览的 admin 页面而改变。这个钩子如下:</p> <div> <div id="highlighter_178877" class="syntaxhighlighter php"> <pre><code class="language-php"><?php do_action( "load-$pagenow" ); ?></code></pre> <br> </div> </div> <p>变量 $pagenow 会变成当前访问页面的名字。例如 new post 页面的钩子是 load-post-new.php,而编辑页面的是 load-post.php。这就使得插件仅仅对特定的 admin 页面执行代码。WordPress 有几个动作和过滤器钩子的名称里面是含有变量的。</p> <p>通常,这些钩子的名字变成给定的内容,使得插件开发者可以在特定的环境下执行代码。</p> <h3>钩子参考列表</h3> <p>虽然在核心里面搜索钩子有助于你增长经验,但是有时你需要一些网上的参考列表。</p> <p>WordPress 在 Codex 中有官方的钩子参考列表。</p> <ul> <li>http://codex.wordpress.org/Plugin_API/Action_Reference</li> <li>http://codex.wordpress.org/Plugin_API/Filter_Reference</li> </ul><p>在 Part-18,开发人员工具箱,将介绍更多帮助插件开发者的工具。</p> <h2>总结</h2> <p>钩子是创建 WordPress 插件的最重要的一环了。每次你开始创建一个插件,你都要把你的插件钩到 WordPress 的动作钩子和过滤器钩子中。钩子是插件开发中必不可少的工具。在了解了钩子之后,就是时候开始创建插件了。</p> </li> </ul> <br> <div></div> <div></div> <div></div> </div> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1294301690194894848"></div> <script type="text/javascript" src="/views/front/js/chanyan.js"></script> <!-- 文章页-底部 动态广告位 --> <div class="youdao-fixed-ad" id="detail_ad_bottom"></div> </div> <div class="col-md-3"> <div class="row" id="ad"> <!-- 文章页-右侧1 动态广告位 --> <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_1"> </div> </div> <!-- 文章页-右侧2 动态广告位 --> <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_2"></div> </div> <!-- 文章页-右侧3 动态广告位 --> <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_3"></div> </div> </div> </div> </div> </div> </div> <div class="container"> <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(WordPress)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1899693341075894272.htm" title="Websoft9 运维面板,全网真正的一键部署应用" target="_blank">Websoft9 运维面板,全网真正的一键部署应用</a> <span class="text-muted"></span> <a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4%E8%BF%90%E7%BB%B4%E8%87%AA%E5%8A%A8%E5%8C%96/1.htm">运维运维自动化</a> <div>一、传统部署的复杂性:以WordPress为例的技术拆解手动部署的典型步骤(耗时约2小时):#1.安装LAMP环境sudoaptinstallapache2mysql-serverphplibapache2-mod-phpphp-mysql#2.配置MySQL(需交互式设置root密码、创建数据库)sudomysql_secure_installationmysql-uroot-p-e"CREAT</div> </li> <li><a href="/article/1899399566386589696.htm" title="WordPress建站给外贸人带来的负担" target="_blank">WordPress建站给外贸人带来的负担</a> <span class="text-muted">小机出海</span> <a class="tag" taget="_blank" href="/search/%E5%BB%BA%E7%AB%99%E5%B8%B8%E8%B0%88/1.htm">建站常谈</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/ssl/1.htm">ssl</a><a class="tag" taget="_blank" href="/search/https/1.htm">https</a> <div>WordPress是全球最大的开源建站平台,有着丰富的主题与插件,尽管功能非常强大,但也给想要建站的外贸人带来了一些负担。一、技术门槛与学习成本1、由于WordPress发展了几十年,里面的功能应有尽有,但往往这些复杂的功能导致建站新手对它的学习成本变得很高,需要理解各个模块与功能点,增加了上手的复杂度。2、WordPress的建站服务商他不会告诉你,你可能需要知道一些代码知识(HTML、CSS、</div> </li> <li><a href="/article/1899108268530266112.htm" title="Synology 部署的 WordPress 無法升級至最新版本時,可以透過以下改良版指南進行排查和解決。" target="_blank">Synology 部署的 WordPress 無法升級至最新版本時,可以透過以下改良版指南進行排查和解決。</a> <span class="text-muted">蠟筆小新工程師</span> <a class="tag" taget="_blank" href="/search/synology/1.htm">synology</a><a class="tag" taget="_blank" href="/search/wordpress/1.htm">wordpress</a> <div>當Synology部署的WordPress無法升級至最新版本時,可以透過以下改良版指南進行排查和解決。我對內容進行了補充和重新組織,希望能幫助你更高效地處理這類問題:權限相關問題處理檢查文件和目錄權限:確保WordPress安裝目錄內的目錄權限設置為755,文件權限設置為664。特殊文件wp-config.php權限應設置為600,以加強安全性。可以使用以下命令在終端中修改:bashchmod-R</div> </li> <li><a href="/article/1897652829280071680.htm" title="哈儿哥网络工作室" target="_blank">哈儿哥网络工作室</a> <span class="text-muted">wodrpress资源分享</span> <a class="tag" taget="_blank" href="/search/%E7%8B%AC%E7%AB%8B%E7%AB%99/1.htm">独立站</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>哈儿哥网络工作室是一家专注于外贸网站搭建与海外品牌营销、网络营销推广的专业机构。凭借多年的行业经验和技术积累,我们致力于为客户提供全面的数字化营销解决方案,帮助企业顺利出海并提升国际竞争力。主要服务内容外贸网站搭建我们提供专业的外贸网站建设服务,包括独立站搭建、商城建设及定制化设计。采用WordPress等主流平台,结合H5自适应布局和欧美设计风格,确保网站界面美观、功能强大且加载速度快。此外,我</div> </li> <li><a href="/article/1897036848203624448.htm" title="rust建深海_使用 Rust 构建个人博客(1) - Warp 后端框架" target="_blank">rust建深海_使用 Rust 构建个人博客(1) - Warp 后端框架</a> <span class="text-muted">Zeldovich Yakov</span> <a class="tag" taget="_blank" href="/search/rust%E5%BB%BA%E6%B7%B1%E6%B5%B7/1.htm">rust建深海</a> <div>需求背景一个朋友买了一个云主机(就是300元3年的那种)云主机配置是:CPU:vCPU2内存:2G硬盘:40G带宽:1M公网IP:1个预装的系统是:Windows2008R2这台机器上,跑了一些他自己的东西,虽然机器整体性能不咋的,但是总觉得还可以再“挖掘”一些性能(挤一挤总是会有的),所以还在跑一个自己的博客。技术选型最初他问我的时候,我就让他用WAMP+WordPress,方便、省事儿,而且W</div> </li> <li><a href="/article/1896699894127718400.htm" title="WPML 多语言 CMS WordPress 插件 v4.5.8" target="_blank">WPML 多语言 CMS WordPress 插件 v4.5.8</a> <span class="text-muted">一路有你网络科技工作室</span> <a class="tag" taget="_blank" href="/search/WordPress/1.htm">WordPress</a><a class="tag" taget="_blank" href="/search/%E5%BB%BA%E7%AB%99%E6%8F%92%E4%BB%B6/1.htm">建站插件</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a> <div>WPML是多语言WordPress网站的事实标准。它为来自世界各地的一百多万个商业网站提供支持。WPML与几乎所有WordPress主题和主要插件兼容。WPML使运行简单的多语言网站变得容易,并为大型和复杂的网站提供高级翻译管理。WPML支持自动翻译,使用高级翻译编辑器进行手动翻译,并提供与数十种专业翻译服务的集成为什么选择WPML?市场上有很多很棒的WordPress翻译插件,但是有很多有效的理</div> </li> <li><a href="/article/1896639504693915648.htm" title="WordPress二次开发实现用户注册审核功能" target="_blank">WordPress二次开发实现用户注册审核功能</a> <span class="text-muted">linlinlove2</span> <a class="tag" taget="_blank" href="/search/wordpress%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91/1.htm">wordpress二次开发</a><a class="tag" taget="_blank" href="/search/wordpress%E4%B8%BB%E9%A2%98%E5%BC%80%E5%8F%91/1.htm">wordpress主题开发</a><a class="tag" taget="_blank" href="/search/wordpress%E5%AE%89%E8%A3%85%E6%90%AD%E5%BB%BA/1.htm">wordpress安装搭建</a><a class="tag" taget="_blank" href="/search/wordpress%E4%BC%98%E5%8C%96%E9%80%9F%E5%BA%A6/1.htm">wordpress优化速度</a><a class="tag" taget="_blank" href="/search/wordpress%E5%A4%96%E8%B4%B8%E7%BD%91%E7%AB%99/1.htm">wordpress外贸网站</a><a class="tag" taget="_blank" href="/search/wordpress%E9%97%AE%E9%A2%98%E5%A4%84%E7%90%86/1.htm">wordpress问题处理</a><a class="tag" taget="_blank" href="/search/wordpress%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91/1.htm">wordpress插件开发</a> <div>WordPress默认直接注册登录了,不需要任何验证,如果被批量注册就麻烦了,所以添加一个审核功能比较好。注册用户默认需要手动审核,审核以后才能登陆,开启审核,可以有效防止用户批量注册。这儿讲解一下如何通过WordPress过滤器来说实现相关功能。1、用户列表界面设置WordPress用户页面,点击顶部用户类型,通过URL中status参数来过滤,那么添加一个参数为:unapproved网址参数为</div> </li> <li><a href="/article/1896337355502055424.htm" title="部署Wordpress(LNMP)+ELK" target="_blank">部署Wordpress(LNMP)+ELK</a> <span class="text-muted">多练项目</span> <a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><a class="tag" taget="_blank" href="/search/%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84/1.htm">系统架构</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/elk/1.htm">elk</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a> <div>LNMP+EFK主机软件服务版本主机名192.168.100.100Nginx-1.18、Filebeatnode100192.168.100.101PHP-5.6.27node101192.168.100.102MySQL5.7node102192.168.100.103Kafkakafka103192.168.100.104Kafkanode104192.168.100.105Kafkanod</div> </li> <li><a href="/article/1896334707285618688.htm" title="阿里云应用镜像选了wordpress与不选的区别?" target="_blank">阿里云应用镜像选了wordpress与不选的区别?</a> <span class="text-muted">云建站架构师rain</span> <a class="tag" taget="_blank" href="/search/%E9%98%BF%E9%87%8C%E4%BA%91/1.htm">阿里云</a><a class="tag" taget="_blank" href="/search/%E8%85%BE%E8%AE%AF%E4%BA%91/1.htm">腾讯云</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a> <div>其实没啥区别的,一般不推荐选择WordPress镜像或者是其他的应用镜像,因为你不会用的,反而会麻烦的。一般推荐的方案是选择纯净的系统镜像,比如安装选择centos7.9系统版本,安装纯净的操作系统镜像,然后再自己去安装宝塔面板。如何安装和更换系统镜像的话,可以参考一下更换系统盘(公共镜像)-云服务器ECS-阿里云正在上传…重新上传取消通过</div> </li> <li><a href="/article/1896326892349353984.htm" title="【wordpress】服务器已有LNMP环境(已运行WordPress),如何配置文档访问功能?" target="_blank">【wordpress】服务器已有LNMP环境(已运行WordPress),如何配置文档访问功能?</a> <span class="text-muted">冰糖雪梨on_chip</span> <a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a><a class="tag" taget="_blank" href="/search/%E6%96%87%E4%BB%B6%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">文件服务器</a> <div>效果如图步骤确定文件存放目录404.html修改配置文件重启nginx服务接下来是从win向linux云服务器上传文件使用Samba服务(没成功)使用xshell上传文件(大文件上传一堆乱码)winscp(好用)效果如图如果url不对,这是404页面步骤确定文件存放目录先确定你要把文件放到哪个目录中,比如我要放在/var/www/jrwei.top/documents中#创建目录sudomkdir</div> </li> <li><a href="/article/1895701058731175936.htm" title="wordpress使用CorePress主题设置项总结" target="_blank">wordpress使用CorePress主题设置项总结</a> <span class="text-muted">linlinlove2</span> <a class="tag" taget="_blank" href="/search/wordpress%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91/1.htm">wordpress二次开发</a><a class="tag" taget="_blank" href="/search/wordpress%E4%B8%BB%E9%A2%98%E5%BC%80%E5%8F%91/1.htm">wordpress主题开发</a> <div>宝塔面板设置软件商店中安装的软件有:(宝塔网站加速3.1)(Nginx1.18.0)(MySql5.6.50)(PHP-5.6)(phpMyAdmin4.4)(Python项目管理器1.9)(又拍云存储4.5)(Linux工具箱1.4)(宝塔SSH终端1.0)(Nginx免费防火墙5.3)网站:首次添加站点选择自动创建数据库网站–>SSL:申请免费Let’sEncrypt证书,并开启强制https</div> </li> <li><a href="/article/1895427576042680320.htm" title="商城源码的框架" target="_blank">商城源码的框架</a> <span class="text-muted">启山智软 商城 源码</span> <a class="tag" taget="_blank" href="/search/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/1.htm">微信小程序</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E6%BA%90/1.htm">开源</a><a class="tag" taget="_blank" href="/search/%E5%B0%8F%E7%A8%8B%E5%BA%8F/1.htm">小程序</a> <div>商城源码的框架通常是基于某种Web开发框架或者电子商务平台来构建的。以下是一些常见的商城源码框架:WooCommerce:基于WordPress的电子商务插件,适用于小型到中型的在线商店。Magento:一个功能强大和灵活的开源电子商务平台,适用于中大型在线商店。Shopify:一个主要面向初创企业和小型商家的云端电子商务平台,易于使用和设置。OpenCart:一个开源的电子商务平台,适用于小型到</div> </li> <li><a href="/article/1895227193575927808.htm" title="开源界的5 大开源许可协议" target="_blank">开源界的5 大开源许可协议</a> <span class="text-muted">tboqi1</span> <a class="tag" taget="_blank" href="/search/%E7%94%B5%E8%84%91%E4%BD%BF%E7%94%A8/1.htm">电脑使用</a> <div>越来越多的开发者与设计者希望将自己的产品开源,以便其他人可以在他们的代码基础上做更多事,开源社区也因此充满生机。在我们所能想到的应用领域,都有开源软件存在(象WordPress,Drupal这些开源CMS)。然而很多人对开源许可并不了解,本文介绍开源领域常用的几种许可协议以及它们之间的区别。什么是许可协议?什么是许可,当你为你的产品签发许可,你是在出让自己的权利,不过,你仍然拥有版权和专利(如果申</div> </li> <li><a href="/article/1895033460981035008.htm" title="WordPress Course Booking System SQL注入漏洞复现 (CVE-2025-22785)(附脚本)" target="_blank">WordPress Course Booking System SQL注入漏洞复现 (CVE-2025-22785)(附脚本)</a> <span class="text-muted">iSee857</span> <a class="tag" taget="_blank" href="/search/%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/1.htm">漏洞复现</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%85%A8/1.htm">安全</a><a class="tag" taget="_blank" href="/search/web%E5%AE%89%E5%85%A8/1.htm">web安全</a> <div>免责申明:本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。0x01产品描述:课程预订系统是一个在线平台,旨在简化课程报名流程。用户可以通过系统浏览可用课程,查看详细的课程描述、时间安排和讲师信息,并通过简单的</div> </li> <li><a href="/article/1892325040683282432.htm" title="关于wordpress建站遇到的问题" target="_blank">关于wordpress建站遇到的问题</a> <span class="text-muted">bug菌¹</span> <a class="tag" taget="_blank" href="/search/%E5%85%A8%E6%A0%88Bug%E8%B0%83%E4%BC%98%28%E5%AE%9E%E6%88%98%E7%89%88%29/1.htm">全栈Bug调优(实战版)</a><a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/CSDN%E9%97%AE%E7%AD%94%E8%A7%A3%E6%83%91%28%E5%85%A8%E6%A0%88%E7%89%88%29/1.htm">CSDN问答解惑(全栈版)</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>本文收录于《全栈Bug调优(实战版)》专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!问题描述使用Wordpress搭建网站遇到的问题我目前使用了AWS的云服务器在这个云服务器的基础上搭建了AApanel(国内叫宝塔面板),与此同时我也购买了域名和做了DN</div> </li> <li><a href="/article/1892322013918326784.htm" title="使用LM Studio在WordPress基于大模型原创文章上稿进行SEO优化" target="_blank">使用LM Studio在WordPress基于大模型原创文章上稿进行SEO优化</a> <span class="text-muted">Mr数据杨</span> <a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/%E8%87%AA%E7%84%B6%E8%AF%AD%E8%A8%80%E6%8A%80%E6%9C%AF/1.htm">自然语言技术</a><a class="tag" taget="_blank" href="/search/wordpress/1.htm">wordpress</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%A8%A1%E5%9E%8B/1.htm">大模型</a><a class="tag" taget="_blank" href="/search/seo/1.htm">seo</a><a class="tag" taget="_blank" href="/search/1024%E7%A8%8B%E5%BA%8F%E5%91%98%E8%8A%82/1.htm">1024程序员节</a> <div>在进行自动化文章生成与发布的流程中,首先需要确保基础配置的完善性和数据的准确性。通过手动设置分类和标签,文章能够在发布时被准确归类,从而提升SEO的效果。通过Excel表格的方式管理这些分类与标签,结合Python脚本,可以高效地实现自动化文章的生成和发布。该流程依赖于对WordPress数据库的操作,包括标签的批量导入、分类和标签的映射,以及通过AI生成内容的自动发布。全面的配置不仅节省了手动处</div> </li> <li><a href="/article/1892321887539752960.htm" title="SEO模板网站的wordpress主题最适合google外贸SEO" target="_blank">SEO模板网站的wordpress主题最适合google外贸SEO</a> <span class="text-muted">podoor</span> <a class="tag" taget="_blank" href="/search/seo/1.htm">seo</a> <div>在寻找最适合Google外贸SEO的WordPress主题时,有几个关键因素需要考虑:速度、SEO友好性、多语言支持、以及是否易于定制。以下是一些推荐的WordPress主题,它们不仅速度快,而且对SEO非常友好,非常适合外贸网站:–模板帝:MobanDi.com是一个完全可定制且免费的WordPress博客主题。它包括适用于个人博客、投资组合、商业博客甚至电子商务网站的入门网站。它反应灵敏,可与</div> </li> <li><a href="/article/1892315715524947968.htm" title="为什么WP建站更适合于谷歌SEO优化?" target="_blank">为什么WP建站更适合于谷歌SEO优化?</a> <span class="text-muted">推广小赵</span> <a class="tag" taget="_blank" href="/search/%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB/1.htm">经验分享</a> <div>在当今数字时代,建立一个网站似乎变得容易,但要构建一个真正能够带来流量和订单的网站却并非易事。特别是在谷歌SEO优化方面,不同的建站程序在SEO支持方面的效果差异显著。对于希望提升搜索引擎表现的用户来说,WordPress无疑是最佳选择。WordPress的优势作为一款强大且广泛使用的内容管理系统(CMS),WordPress最大的优势在于其灵活性和可扩展性。该平台允许用户利用丰富的SEO插件来优</div> </li> <li><a href="/article/1892024240522194944.htm" title="宝塔面板如何设置SSL证书并访问HTTPS" target="_blank">宝塔面板如何设置SSL证书并访问HTTPS</a> <span class="text-muted">vpssf</span> <a class="tag" taget="_blank" href="/search/Linux%E8%BF%90%E7%BB%B4%E6%95%99%E7%A8%8B/1.htm">Linux运维教程</a><a class="tag" taget="_blank" href="/search/%E5%AE%9D%E5%A1%94%E9%9D%A2%E6%9D%BF%E6%95%99%E7%A8%8B/1.htm">宝塔面板教程</a><a class="tag" taget="_blank" href="/search/WordPress%E6%95%99%E7%A8%8B/1.htm">WordPress教程</a> <div>概述如果还有不了解宝塔面板怎么使用的小伙伴,可以看下前文:宝塔面板教程(1)基于云服务器搭建宝塔面板教程最全详解宝塔面板教程(2)宝塔面板添加WordPress站点详细图文教程宝塔面板教程(3)基于宝塔面板成功配置网站SSL安全证书宝塔面板教程(4)WordPress网站的备份与恢复(宝塔面板)宝塔面板教程(5)WordPress网站程序和数据库定时备份到七牛云存储图文教程宝塔面板教程(6)Wor</div> </li> <li><a href="/article/1892019949770174464.htm" title="宝塔面板设置SSL完整图文教程" target="_blank">宝塔面板设置SSL完整图文教程</a> <span class="text-muted">青云网运维</span> <a class="tag" taget="_blank" href="/search/%E5%AE%9D%E5%A1%94%E9%9D%A2%E6%9D%BF%E6%95%99%E7%A8%8B/1.htm">宝塔面板教程</a><a class="tag" taget="_blank" href="/search/WordPress%E6%95%99%E7%A8%8B/1.htm">WordPress教程</a> <div>概述如果还有不了解宝塔面板怎么使用的小伙伴,可以看下前文:宝塔面板教程(1)基于云服务器搭建宝塔面板教程最全详解宝塔面板教程(2)宝塔面板添加WordPress站点详细图文教程宝塔面板教程(3)基于宝塔面板成功配置网站SSL安全证书宝塔面板教程(4)WordPress网站的备份与恢复(宝塔面板)宝塔面板教程(5)WordPress网站程序和数据库定时备份到七牛云存储图文教程宝塔面板教程(6)Wor</div> </li> <li><a href="/article/1892012006286880768.htm" title="宝塔面板绑定域名访问-自定义SSL证书(消除不安全提示)" target="_blank">宝塔面板绑定域名访问-自定义SSL证书(消除不安全提示)</a> <span class="text-muted">大叔建站笔记</span> <a class="tag" taget="_blank" href="/search/%E5%AE%9D%E5%A1%94%E9%9D%A2%E6%9D%BF/1.htm">宝塔面板</a><a class="tag" taget="_blank" href="/search/%E4%B8%8A%E4%BA%91%E6%95%99%E7%A8%8B/1.htm">上云教程</a> <div>前提条件你熟悉宝塔面板搭建网站。我这个建站老鸟都在用宝塔面板建站,主要就是图它的节省时间和精力。大家有不熟悉宝塔面板使用的,可以查看文章:宝塔面板添加WordPress站点详细图文教程之后你就完全可以入门了。你拥有一台云服务器和一个万网域名。这个没什么好说的,网站的成功搭建少不了这两个东西,算是基础条件了。如果你不了解建一个网站的基本流程,可以阅读教程:个人和企业搭建网站主要流程以及六个基本步骤成</div> </li> <li><a href="/article/1890389389222146048.htm" title="wordpress模板文件结构超详解" target="_blank">wordpress模板文件结构超详解</a> <span class="text-muted">still</span> <a class="tag" taget="_blank" href="/search/wordpress/1.htm">wordpress</a> <div>wordpress网站建设中,主题的制作是最为核心的环节。了解模板文件结构是模板制作的第一步,本文所讲的模板文件结构包括两部分,一是指以文件名为概念的文件结构,二是指文件内容的代码结构。一、如何使模板文件起作用↑wordpress模板文件夹放置于/wp-content/themes/下,开发者只需将自己的模板文件全部置于一个文件夹中,将文件夹置于该目录下,wordpress系统就会自动检测,发现模</div> </li> <li><a href="/article/1889450889928830976.htm" title="宝塔一键部署Wordpress无法打开,显示响应时间太长" target="_blank">宝塔一键部署Wordpress无法打开,显示响应时间太长</a> <span class="text-muted">黎想</span> <a class="tag" taget="_blank" href="/search/Wordpress%E5%BC%80%E5%8F%91/1.htm">Wordpress开发</a><a class="tag" taget="_blank" href="/search/php/1.htm">php</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%AB%99/1.htm">网站</a><a class="tag" taget="_blank" href="/search/Wordpress/1.htm">Wordpress</a><a class="tag" taget="_blank" href="/search/SEO/1.htm">SEO</a><a class="tag" taget="_blank" href="/search/wordpress/1.htm">wordpress</a> <div>之前一直使用宝塔管理服务器,近期又折腾AI,宝塔是卸了装装了卸,服务器安全组规则也是不断地添加删除。DeepSeek最后终于部署好了,但是突然发现建设其他站点时,都是无法访问,这是啥原因了?最后通过找资料,自己研究捣鼓发现,宝塔一键部署Wordpress无法打开,打开时显示响应时间太长,其实原因很简单,就是因为服务器组安全端口未打开。我们在使用腾讯云、阿里云等云服务时,需要注意端口放行问题。确保在</div> </li> <li><a href="/article/1889086491796238336.htm" title="MongoDB 的使用场景" target="_blank">MongoDB 的使用场景</a> <span class="text-muted">yqcoder</span> <a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a> <div>一、内容管理系统1.博客平台文章内容、作者信息、标签、评论等数据结构多样,MongoDB的无模式特性可轻松应对。比如WordPress等博客系统,使用MongoDB能灵活存储不同格式和长度的文章内容,以及与文章相关的各种元数据。2.新闻网站新闻稿件、多媒体资源、分类信息等更新频繁且结构多变。以澎湃新闻为例,其新闻数据可能包含文字、图片、视频等多种类型,用MongoDB可方便地存储和管理这些不同类型</div> </li> <li><a href="/article/1888644442722725888.htm" title="【wordpress】如何让wordpress升级时无需输入ftp用户名和密码" target="_blank">【wordpress】如何让wordpress升级时无需输入ftp用户名和密码</a> <span class="text-muted">冰糖雪梨on_chip</span> <a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><a class="tag" taget="_blank" href="/search/wordpress/1.htm">wordpress</a> <div>vim/usr/share/nginx/html/wordpress/wp-config.php添加以下三行define("FS_METHOD","direct");define("FS_CHMOD_DIR",0777);define("FS_CHMOD_FILE",0777);退出vim更改权限chmod-R777/usr/share/nginx/html/wordpress/chown-Rng</div> </li> <li><a href="/article/1887447009527394304.htm" title="根据浏览器语言判断wordpress访问不同语言的站点" target="_blank">根据浏览器语言判断wordpress访问不同语言的站点</a> <span class="text-muted">wodrpress资源分享</span> <a class="tag" taget="_blank" href="/search/wordpress/1.htm">wordpress</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/wordpress/1.htm">wordpress</a> <div>根据当前用户使用的浏览器语言判断,让wordpress按语言访问不同语言的站点。wordpress多语言网站,分别访问的一个好办法。document.addEventListener('DOMContentLoaded',function(){varbrowserLang=navigator.language||navigator.userLanguage;varlang=browserLang.</div> </li> <li><a href="/article/1885907647002112000.htm" title="pythonocc的安装" target="_blank">pythonocc的安装</a> <span class="text-muted">Tony_xxx</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>https://pythonocc.wordpress.com/2013/03/04/installing-on-ubuntu-12-04/官方教程https://github.com/tpaviot/oce/blob/master/BUILD.Unix.mdhttps://github.com/tpaviot/pythonocc-core/blob/master/INSTALL.mdgitclo</div> </li> <li><a href="/article/1885378293838966784.htm" title="wordpress调用指定ID页面的链接" target="_blank">wordpress调用指定ID页面的链接</a> <span class="text-muted">wodrpress资源分享</span> <a class="tag" taget="_blank" href="/search/wordpress/1.htm">wordpress</a><a class="tag" taget="_blank" href="/search/wordpress/1.htm">wordpress</a> <div>在WordPress中,如果你想调用一个指定ID的页面链接,可以使用以下几种方法:方法一:使用页面ID你可以直接使用页面的ID来生成链接。例如,如果你想链接到ID为123的页面,可以使用以下代码:">访问页面这里的get_permalink()函数会返回指定页面ID的永久链接。方法二:使用页面别名(Slug)如果你的页面有一个别名(slug),你也可以使用这个别名来生成链接。例如,如果页面的slu</div> </li> <li><a href="/article/1885373374700515328.htm" title="wordpress外贸独立站常用询盘软件" target="_blank">wordpress外贸独立站常用询盘软件</a> <span class="text-muted">wodrpress资源分享</span> <a class="tag" taget="_blank" href="/search/%E7%8B%AC%E7%AB%8B%E7%AB%99/1.htm">独立站</a><a class="tag" taget="_blank" href="/search/%E7%8B%AC%E7%AB%8B%E7%AB%99/1.htm">独立站</a> <div>LiveChatLiveChat是一家提供实时聊天软件的公司,帮助企业通过其平台与客户进行即时通讯,提高客户满意度和忠诚度。他们的产品允许企业在网站、应用程序或电子邮件等多个渠道与客户互动,从而提升客户体验并促进销售增长。LiveChat的软件特点包括:实时聊天窗口:允许客服人员与客户进行即时对话,解决疑问或提供信息。自动化问候与响应:设置自动弹出的问候消息,以及根据预设规则自动回复常见问题的功能</div> </li> <li><a href="/article/1885339577347010560.htm" title="wordpress代码结构解析" target="_blank">wordpress代码结构解析</a> <span class="text-muted">程序员阿凡提</span> <a class="tag" taget="_blank" href="/search/PHP%E5%AE%9E%E6%88%98%E6%95%99%E7%A8%8B/1.htm">PHP实战教程</a><a class="tag" taget="_blank" href="/search/WordPress/1.htm">WordPress</a><a class="tag" taget="_blank" href="/search/%E4%BB%A3%E7%A0%81/1.htm">代码</a><a class="tag" taget="_blank" href="/search/%E8%A7%A3%E6%9E%90/1.htm">解析</a> <div>WordPress是一个基于PHP和MySQL的开源内容管理系统(CMS),广泛用于构建网站和博客。要解析WordPress代码,首先需要了解其核心结构、主要文件和常用的函数。以下是WordPress代码解析的基本指南:---###1.**WordPress核心文件结构**WordPress的核心文件位于安装目录下,以下是一些关键文件和目录:-**wp-admin**:包含WordPress后台管</div> </li> <li><a href="/article/80.htm" title="java杨辉三角" target="_blank">java杨辉三角</a> <span class="text-muted">3213213333332132</span> <a class="tag" taget="_blank" href="/search/java%E5%9F%BA%E7%A1%80/1.htm">java基础</a> <div> package com.algorithm; /** * @Description 杨辉三角 * @author FuJianyong * 2015-1-22上午10:10:59 */ public class YangHui { public static void main(String[] args) { //初始化二维数组长度 int[][] y</div> </li> <li><a href="/article/207.htm" title="《大话重构》之大布局的辛酸历史" target="_blank">《大话重构》之大布局的辛酸历史</a> <span class="text-muted">白糖_</span> <a class="tag" taget="_blank" href="/search/%E9%87%8D%E6%9E%84/1.htm">重构</a> <div>《大话重构》中提到“大布局你伤不起”,如果企图重构一个陈旧的大型系统是有非常大的风险,重构不是想象中那么简单。我目前所在公司正好对产品做了一次“大布局重构”,下面我就分享这个“大布局”项目经验给大家。   背景         公司专注于企业级管理产品软件,企业有大中小之分,在2000年初公司用JSP/Servlet开发了一套针对中</div> </li> <li><a href="/article/334.htm" title="电驴链接在线视频播放源码" target="_blank">电驴链接在线视频播放源码</a> <span class="text-muted">dubinwei</span> <a class="tag" taget="_blank" href="/search/%E6%BA%90%E7%A0%81/1.htm">源码</a><a class="tag" taget="_blank" href="/search/%E7%94%B5%E9%A9%B4/1.htm">电驴</a><a class="tag" taget="_blank" href="/search/%E6%92%AD%E6%94%BE%E5%99%A8/1.htm">播放器</a><a class="tag" taget="_blank" href="/search/%E8%A7%86%E9%A2%91/1.htm">视频</a><a class="tag" taget="_blank" href="/search/ed2k/1.htm">ed2k</a> <div>本项目是个搜索电驴(ed2k)链接的应用,借助于磁力视频播放器(官网: http://loveandroid.duapp.com/ 开放平台),可以实现在线播放视频,也可以用迅雷或者其他下载工具下载。 项目源码: http://git.oschina.net/svo/Emule,动态更新。也可从附件中下载。 项目源码依赖于两个库项目,库项目一链接: http://git.oschina.</div> </li> <li><a href="/article/461.htm" title="Javascript中函数的toString()方法" target="_blank">Javascript中函数的toString()方法</a> <span class="text-muted">周凡杨</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/js/1.htm">js</a><a class="tag" taget="_blank" href="/search/toString/1.htm">toString</a><a class="tag" taget="_blank" href="/search/function/1.htm">function</a><a class="tag" taget="_blank" href="/search/object/1.htm">object</a> <div>简述     The toString() method returns a string representing the source code of the function.     简译之,Javascript的toString()方法返回一个代表函数源代码的字符串。 句法     function.</div> </li> <li><a href="/article/588.htm" title="struts处理自定义异常" target="_blank">struts处理自定义异常</a> <span class="text-muted">g21121</span> <a class="tag" taget="_blank" href="/search/struts/1.htm">struts</a> <div>很多时候我们会用到自定义异常来表示特定的错误情况,自定义异常比较简单,只要分清是运行时异常还是非运行时异常即可,运行时异常不需要捕获,继承自RuntimeException,是由容器自己抛出,例如空指针异常。 非运行时异常继承自Exception,在抛出后需要捕获,例如文件未找到异常。 此处我们用的是非运行时异常,首先定义一个异常LoginException: /** * 类描述:登录相</div> </li> <li><a href="/article/715.htm" title="Linux中find常见用法示例" target="_blank">Linux中find常见用法示例</a> <span class="text-muted">510888780</span> <a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a> <div>Linux中find常见用法示例 ·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \; find命令的参数;</div> </li> <li><a href="/article/842.htm" title="SpringMVC的各种参数绑定方式" target="_blank">SpringMVC的各种参数绑定方式</a> <span class="text-muted">Harry642</span> <a class="tag" taget="_blank" href="/search/springMVC/1.htm">springMVC</a><a class="tag" taget="_blank" href="/search/%E7%BB%91%E5%AE%9A/1.htm">绑定</a><a class="tag" taget="_blank" href="/search/%E8%A1%A8%E5%8D%95/1.htm">表单</a> <div>1. 基本数据类型(以int为例,其他类似): Controller代码: @RequestMapping("saysth.do") public void test(int count) { } 表单代码: <form action="saysth.do" method="post&q</div> </li> <li><a href="/article/969.htm" title="Java 获取Oracle ROWID" target="_blank">Java 获取Oracle ROWID</a> <span class="text-muted">aijuans</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a> <div> A ROWID is an identification tag unique for each row of an Oracle Database table. The ROWID can be thought of as a virtual column, containing the ID for each row. The oracle.sql.ROWID class i</div> </li> <li><a href="/article/1096.htm" title="java获取方法的参数名" target="_blank">java获取方法的参数名</a> <span class="text-muted">antlove</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/jdk/1.htm">jdk</a><a class="tag" taget="_blank" href="/search/parameter/1.htm">parameter</a><a class="tag" taget="_blank" href="/search/method/1.htm">method</a><a class="tag" taget="_blank" href="/search/reflect/1.htm">reflect</a> <div>reflect.ClassInformationUtil.java package reflect; import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; import javassist.Modifier; import javassist.bytecode.CodeAtt</div> </li> <li><a href="/article/1223.htm" title="JAVA正则表达式匹配 查找 替换 提取操作" target="_blank">JAVA正则表达式匹配 查找 替换 提取操作</a> <span class="text-muted">百合不是茶</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/1.htm">正则表达式</a><a class="tag" taget="_blank" href="/search/%E6%9B%BF%E6%8D%A2/1.htm">替换</a><a class="tag" taget="_blank" href="/search/%E6%8F%90%E5%8F%96/1.htm">提取</a><a class="tag" taget="_blank" href="/search/%E6%9F%A5%E6%89%BE/1.htm">查找</a> <div>正则表达式的查找;主要是用到String类中的split();       String str;      str.split();方法中传入按照什么规则截取,返回一个String数组   常见的截取规则: str.split("\\.")按照.来截取 str.</div> </li> <li><a href="/article/1350.htm" title="Java中equals()与hashCode()方法详解" target="_blank">Java中equals()与hashCode()方法详解</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/set/1.htm">set</a><a class="tag" taget="_blank" href="/search/equals%28%29/1.htm">equals()</a><a class="tag" taget="_blank" href="/search/hashCode%28%29/1.htm">hashCode()</a> <div>一.equals()方法详解     equals()方法在object类中定义如下:  public boolean equals(Object obj) { return (this == obj); }    很明显是对两个对象的地址值进行的比较(即比较引用是否相同)。但是我们知道,String 、Math、I</div> </li> <li><a href="/article/1477.htm" title="精通Oracle10编程SQL(4)使用SQL语句" target="_blank">精通Oracle10编程SQL(4)使用SQL语句</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/plsql/1.htm">plsql</a> <div>--工资级别表 create table SALGRADE ( GRADE NUMBER(10), LOSAL NUMBER(10,2), HISAL NUMBER(10,2) ) insert into SALGRADE values(1,0,100); insert into SALGRADE values(2,100,200); inser</div> </li> <li><a href="/article/1604.htm" title="【Nginx二】Nginx作为静态文件HTTP服务器" target="_blank">【Nginx二】Nginx作为静态文件HTTP服务器</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/HTTP%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">HTTP服务器</a> <div> Nginx作为静态文件HTTP服务器 在本地系统中创建/data/www目录,存放html文件(包括index.html) 创建/data/images目录,存放imags图片 在主配置文件中添加http指令   http { server { listen 80; server_name </div> </li> <li><a href="/article/1731.htm" title="kafka获得最新partition offset" target="_blank">kafka获得最新partition offset</a> <span class="text-muted">blackproof</span> <a class="tag" taget="_blank" href="/search/kafka/1.htm">kafka</a><a class="tag" taget="_blank" href="/search/partition/1.htm">partition</a><a class="tag" taget="_blank" href="/search/offset/1.htm">offset</a><a class="tag" taget="_blank" href="/search/%E6%9C%80%E6%96%B0/1.htm">最新</a> <div>kafka获得partition下标,需要用到kafka的simpleconsumer   import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.</div> </li> <li><a href="/article/1858.htm" title="centos 7安装docker两种方式" target="_blank">centos 7安装docker两种方式</a> <span class="text-muted">ronin47</span> <div>      第一种是采用yum 方式              yum install -y docker           </div> </li> <li><a href="/article/1985.htm" title="java-60-在O(1)时间删除链表结点" target="_blank">java-60-在O(1)时间删除链表结点</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div> public class DeleteNode_O1_Time { /** * Q 60 在O(1)时间删除链表结点 * 给定链表的头指针和一个结点指针(!!),在O(1)时间删除该结点 * * Assume the list is: * head->...->nodeToDelete->mNode->nNode->..</div> </li> <li><a href="/article/2112.htm" title="nginx利用proxy_cache来缓存文件" target="_blank">nginx利用proxy_cache来缓存文件</a> <span class="text-muted">cfyme</span> <a class="tag" taget="_blank" href="/search/cache/1.htm">cache</a> <div>user  zhangy users; worker_processes 10; error_log  /var/vlogs/nginx_error.log  crit; pid        /var/vlogs/nginx.pid; #Specifies the value for ma</div> </li> <li><a href="/article/2239.htm" title="[JWFD开源工作流]JWFD嵌入式语法分析器负号的使用问题" target="_blank">[JWFD开源工作流]JWFD嵌入式语法分析器负号的使用问题</a> <span class="text-muted">comsci</span> <a class="tag" taget="_blank" href="/search/%E5%B5%8C%E5%85%A5%E5%BC%8F/1.htm">嵌入式</a> <div>     假如我们需要用JWFD的语法分析模块定义一个带负号的方程式,直接在方程式之前添加负号是不正确的,而必须这样做:     string str01 = "a=3.14;b=2.71;c=0;c-((a*a)+(b*b))"     定义一个0整数c,然后用这个整数c去</div> </li> <li><a href="/article/2366.htm" title="如何集成支付宝官方文档" target="_blank">如何集成支付宝官方文档</a> <span class="text-muted">dai_lm</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>官方文档下载地址 https://b.alipay.com/order/productDetail.htm?productId=2012120700377310&tabId=4#ps-tabinfo-hash 集成的必要条件 1. 需要有自己的Server接收支付宝的消息 2. 需要先制作app,然后提交支付宝审核,通过后才能集成 调试的时候估计会真的扣款,请注意 </div> </li> <li><a href="/article/2493.htm" title="应该在什么时候使用Hadoop" target="_blank">应该在什么时候使用Hadoop</a> <span class="text-muted">datamachine</span> <a class="tag" taget="_blank" href="/search/hadoop/1.htm">hadoop</a> <div>原帖地址:http://blog.chinaunix.net/uid-301743-id-3925358.html 存档,某些观点与我不谋而合,过度技术化不可取,且hadoop并非万能。 --------------------------------------------万能的分割线-------------------------------- 有人问我,“你在大数据和Hado</div> </li> <li><a href="/article/2620.htm" title="在GridView中对于有外键的字段使用关联模型进行搜索和排序" target="_blank">在GridView中对于有外键的字段使用关联模型进行搜索和排序</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/yii/1.htm">yii</a> <div>在GridView中使用关联模型进行搜索和排序 首先我们有两个模型它们直接有关联: class Author extends CActiveRecord { ... } class Post extends CActiveRecord { ... function relations() { return array( '</div> </li> <li><a href="/article/2747.htm" title="使用NSString 的格式化大全" target="_blank">使用NSString 的格式化大全</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/Objective-C/1.htm">Objective-C</a> <div>格式定义The format specifiers supported by the NSString formatting methods and CFString formatting functions follow the IEEE printf specification; the specifiers are summarized in Table 1. Note that you c</div> </li> <li><a href="/article/2874.htm" title="使用activeX插件对象object滚动有重影" target="_blank">使用activeX插件对象object滚动有重影</a> <span class="text-muted">蕃薯耀</span> <a class="tag" taget="_blank" href="/search/activeX%E6%8F%92%E4%BB%B6/1.htm">activeX插件</a><a class="tag" taget="_blank" href="/search/%E6%BB%9A%E5%8A%A8%E6%9C%89%E9%87%8D%E5%BD%B1/1.htm">滚动有重影</a> <div>  使用activeX插件对象object滚动有重影   <object style="width:0;" id="abc" classid="CLSID:D3E3970F-2927-9680-BBB4-5D0889909DF6" codebase="activex/OAX339.CAB#</div> </li> <li><a href="/article/3001.htm" title="SpringMVC4零配置" target="_blank">SpringMVC4零配置</a> <span class="text-muted">hanqunfeng</span> <a class="tag" taget="_blank" href="/search/springmvc4/1.htm">springmvc4</a> <div>基于Servlet3.0规范和SpringMVC4注解式配置方式,实现零xml配置,弄了个小demo,供交流讨论。     项目说明如下: 1.db.sql是项目中用到的表,数据库使用的是oracle11g 2.该项目使用mvn进行管理,私服为自搭建nexus,项目只用到一个第三方 jar,就是oracle的驱动; 3.默认项目为零配置启动,如果需要更改启动方式,请</div> </li> <li><a href="/article/3128.htm" title="《开源框架那点事儿16》:缓存相关代码的演变" target="_blank">《开源框架那点事儿16》:缓存相关代码的演变</a> <span class="text-muted">j2eetop</span> <a class="tag" taget="_blank" href="/search/%E5%BC%80%E6%BA%90%E6%A1%86%E6%9E%B6/1.htm">开源框架</a> <div>问题引入 上次我参与某个大型项目的优化工作,由于系统要求有比较高的TPS,因此就免不了要使用缓冲。 该项目中用的缓冲比较多,有MemCache,有Redis,有的还需要提供二级缓冲,也就是说应用服务器这层也可以设置一些缓冲。 当然去看相关实现代代码的时候,大致是下面的样子。 [java] view plain copy print ? public vo</div> </li> <li><a href="/article/3255.htm" title="AngularJS浅析" target="_blank">AngularJS浅析</a> <span class="text-muted">kvhur</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a> <div>概念 AngularJS is a structural framework for dynamic web apps. 了解更多详情请见原文链接:http://www.gbtags.com/gb/share/5726.htm Directive 扩展html,给html添加声明语句,以便实现自己的需求。对于页面中html元素以ng为前缀的属性名称,ng是angular的命名空间</div> </li> <li><a href="/article/3382.htm" title="架构师之jdk的bug排查(一)---------------split的点号陷阱" target="_blank">架构师之jdk的bug排查(一)---------------split的点号陷阱</a> <span class="text-muted">nannan408</span> <a class="tag" taget="_blank" href="/search/split/1.htm">split</a> <div>1.前言.    jdk1.6的lang包的split方法是有bug的,它不能有效识别A.b.c这种类型,导致截取长度始终是0.而对于其他字符,则无此问题.不知道官方有没有修复这个bug. 2.代码 String[] paths = "object.object2.prop11".split("'"); System.ou</div> </li> <li><a href="/article/3509.htm" title="如何对10亿数据量级的mongoDB作高效的全表扫描" target="_blank">如何对10亿数据量级的mongoDB作高效的全表扫描</a> <span class="text-muted">quentinXXZ</span> <a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a> <div>  本文链接:  http://quentinXXZ.iteye.com/blog/2149440 一、正常情况下,不应该有这种需求 首先,大家应该有个概念,标题中的这个问题,在大多情况下是一个伪命题,不应该被提出来。要知道,对于一般较大数据量的数据库,全表查询,这种操作一般情况下是不应该出现的,在做正常查询的时候,如果是范围查询,你至少应该要加上limit。 说一下,</div> </li> <li><a href="/article/3636.htm" title="C语言算法之水仙花数" target="_blank">C语言算法之水仙花数</a> <span class="text-muted">qiufeihu</span> <a class="tag" taget="_blank" href="/search/c/1.htm">c</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a> <div>/** * 水仙花数 */ #include <stdio.h> #define N 10 int main() { int x,y,z; for(x=1;x<=N;x++) for(y=0;y<=N;y++) for(z=0;z<=N;z++) if(x*100+y*10+z == x*x*x</div> </li> <li><a href="/article/3763.htm" title="JSP指令" target="_blank">JSP指令</a> <span class="text-muted">wyzuomumu</span> <a class="tag" taget="_blank" href="/search/jsp/1.htm">jsp</a> <div> jsp指令的一般语法格式: <%@ 指令名 属性 =”值 ” %> 常用的三种指令: page,include,taglib page指令语法形式: <%@ page 属性 1=”值 1” 属性 2=”值 2”%> include指令语法形式: <%@include file=”relative url”%> (jsp可以通过 include</div> </li> </ul> </div> </div> </div> <div> <div class="container"> <div class="indexes"> <strong>按字母分类:</strong> <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a> </div> </div> </div> <footer id="footer" class="mb30 mt30"> <div class="container"> <div class="footBglm"> <a target="_blank" href="/">首页</a> - <a target="_blank" href="/custom/about.htm">关于我们</a> - <a target="_blank" href="/search/Java/1.htm">站内搜索</a> - <a target="_blank" href="/sitemap.txt">Sitemap</a> - <a target="_blank" href="/custom/delete.htm">侵权投诉</a> </div> <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved. <!-- <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>--> </div> </div> </footer> <!-- 代码高亮 --> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script> <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/> <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script> </body> </html>