阅读视图

发现新文章,点击刷新页面。

wordpress 获得当前文章真实序号的方法

想在主题里利用一下这个小功能。
那些抄来抄去的都包了浆的所谓办法都是在后续的ID上作文章,根本没有切中问题的本质。因为在wordpress的设计思想中,万物皆post,根本没把ID的增长当回事。想通过限制自动保持、自动版本、限制媒体什么的解决方案是缘木求鱼,根本不治本。
其实“取连续的文章序号”换个思路,就是取“截止当前发表时间,它的前面还有多少篇”这么一个简单问题。刚好wordpress的核心类WP_Query支持根据时间检索,而时间检索的参数里刚好有个’before’。一拍即合。
下面就是代码。注意:此代码要在loop内部使用。

get_real_post_id() {
    if ( !is_single() ){
        return;
    }
    global $post;
    if ( 'publish' !== $post->post_status
		&& 'private' !== $post->post_status) {
        return;
    }
    $args = array(
        'post_type' => 'post',
        'post_status' => array('publish', 'private'),
        'post_per_page' => -1,
        'fields' => 'ids',
        'date_query' => array(
            'before' => $post->post_date,
        ),
    );
    $the_query = new WP_Query($args);
    return $the_query->post_count;
}

简单解释一下:
因为要用到post的ID、post_status和post_date,所以直接用了loop循环中存在的全局变量$post。不用这个全局变量,改用get系列的函数也是一样的。
检索的post类型,我用的是publish和private。这个参是个数组,可以根据需要自行增减。
fields设成ids,意思是返回值接受id。这么写是因为有人说这样可以加快执行速度,并没有实际证据。

date_query是重头戏。
before可以接受的是date string。而无论你的时间格式设成什么样,$post->post_date都刚好是个标准的时间字符串,而且还精确到秒,所以直接放进去即可。
这里其实省略了一个默认参“column”=“post_date”,也就是给before参赋的值。可以选择的还有“post_date_gmt”,“post_modified”,“post_modified_gmt”。都是字面意思,有需要自己替换就行。
还有就是,before默认生成的运算符是小于等于,也就是取得的数包括了当前贴自身。如果要取得除自己以外的数量,自行减1,或者增加参数post__not_in均可达到目的。

对了还有,get_posts跟WP_Query本质上是一个东西,同样的参数,用get_posts调用,也能起到同样的效果。但是实际执行时,get_posts为了得到返回值,需要多执行一次qurey。而使用WP_Query的时候,直接取成员post_count即可,并不需要把post真的检索出来,相对来说效率更高。

此方案的优点是动态获取,删帖或者转换帖子类型,甚至无耻地修改发帖时间,都不会影响序号的连续性。
缺点就是进行了一次数据库操作,会耽误一丢丢时间。不过据说WP_Query默认操作的是缓存,影响应该没那么大。
以上。


  • (1):地球球花演邦女郎的时候已经是五旬老太了,不在讨论之列
  • (2):本作日版发售后3天,任天堂的下一代掌机NDS在北美上市
  • (3):本作两个流行的汉化版都有大问题。一个D商汉化版不能正常存档,另一个汉化版切换到饺子开始的中间几个人物后会死机。
  • (4):五人分工:辽冀鲁,津京,江浙沪,闽粤桂,深圳+长江(武汉)
  • (5):本来还有个汤球球,但他把机器和卡一起卖给了我。

Linux下C语言判断samba服务器是否mount成功

最新的项目需要向网络共享服务器定时上传资料。但是客户的网络环境不知道咋配的,mount的执行总是有延时,并且还经常掉线。所以在上传文件之前我必须判断mount的目录是否是一个samba共享目录。
在我的环境下,这个共享文件夹是/mnt/smb/。这个文件夹有如下特性:
1:如果mount成功,它就是共享服务器的根文件夹,否则只是一个普通的Linux文件夹。
2:如果启动时网络有问题,那么fstab的自动mount(cifs方式)会执行失败。
3:fstab不归我管,也就是我没有改变mount时机的权力。
4:如果启动时网络没有问题,而后来断网,那么这个文件夹的仍旧处于挂载状态。所以使用mount命令是走不通的。
查找资料以后,我决定采用ping+判断文件夹文件系统的方法,来判断文件夹是否已经被mount。

用ping命令结合popen函数判断网络情况

断网是mount失败的充分非必要条件。之所以要先判断网络联通情况,是因为如果网络是中途切断的,cifs有一个180秒的漫长等待时间。此期间去调用(网络文件夹)的文件系统,也会等到cifs判断网络切断的时间点,才返回一个“网络临时切断”的errno(具体值忘了)。而这个cifs的等待时间以后,再去取网络文件夹的文件系统,就会立即返回Host挂了的errno(具体值也忘了)了。
为了节省这个最多达到180秒的时间,我ping一下不就行了。当然,如果服务器把ICMP给封了,当我没说。

static int ping_server(const char* ip_addr)
{
    int ret = 0;
    if (!ip_addr)
    {
        return ret;
    }
    char buffer[1024] = {0};
    char str_cmd[MAX_PATH] = {0};
    sprintf(str_cmd, "ping -c 1 -W 2 %s", ip_addr);
    FILE* pipe = popen(str_cmd, "r");
    if (!pipe)
    {
        printf("exec ping popen failed. ERROR:%d:%s", errno, strerror(errno));
        return ret;
    }
    sleep(1);
    int rd = fread(buffer, 1, 1024, pipe);
    if (rd <=0)
    {
        printf("exec ping timeout.");
    }
    else if( NULL != strstr( buffer, "ttl=" ) )
    {
        ret = 1;
    }
    pclose(pipe);
    return ret;
}

popen函数是个挺有趣的函数,它在stdio.h里就有。作用是起一个process来执行shell命令。跟system相比,它的等待过程更灵活,获取命令在屏幕上的输出内容也更方便。
这里的fread有点魔性。因为我写的ping命令配合参数,意思是ping一次,等待2秒。而我在fread之前只等了1秒。这样,如果断网,我在等待1秒后读取的屏幕内容为空,便可以立刻返回,而不必等待整个ping命令结束。判断接通就很简单了,看输出的内容里有没有“ttl=”的文字,常规操作。

用statfs函数判断文件夹文件系统属性

这个函数用起来就有点麻烦了。
首先要引一个系统头文件“sys/vfs.h”。然后里面那些相貌清奇的文件系统的宏定义被一层一层引用,很难找。于是我索性自己重新定义了一下,好孩子千万不要学。
文档在这里

#include <sys/vfs.h>
#ifndef SMB2_MAGIC_NUMBER
#define SMB2_MAGIC_NUMBER     0xfe534d42
#endif
static int is_smb_fs(void)
{
    struct statfs fs;
    int ret = statfs("/mnt/smb", &fs);

    if (0 == ret && (SMB2_MAGIC_NUMBER == fs.f_type))
    {
        printf(   "check smb dir [mnt/smb] ret = %d status = %llx", ret, fs.f_type);
        return 1;
    }
    return 0;
}

将上面两个函数封装成进一个函数

static int is_smb_folder_connected(const char* ip_addr)
{
    if (ping_server(ip_addr))
    {
        return is_smb_fs();
    }
    return 0;
}

main函数略。
收工。


  • (1):本来还有个汤球球,但他把机器和卡一起卖给了我。
  • (2):真正的谜底是“贵妃红”,有人听说过这种花么?
❌