PHP数组转字符串拼接代码

function ToUrlParams(array $array)
    {
        $buff = "";
        foreach ($array as $k => $v)
        {
            if($v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }
        
        $buff = trim($buff, "&");
        return $buff;
}

调用方法:ToUrlParams($data)

谷歌动态口令(身份验证器)PHPDEMO

新建示例文件:demo.php

<?php
require_once 'google.php';
 
$ga = new PHPGangsta_GoogleAuthenticator();
 
//创建一个新的"安全密匙SecretKey"
//把本次的"安全密匙SecretKey" 入库,和账户关系绑定,客户端也是绑定这同一个"安全密匙SecretKey"
$secret = $ga->createSecret();
echo "安全密匙SecretKey: ".$secret."\n\n";
 
$qrCodeUrl = $ga->getQRCodeGoogleUrl('demo@vanwei.com', $secret); //第一个参数是"标识",第二个参数为"安全密匙SecretKey" 生成二维码信息
echo "Google Charts URL for the QR-Code: ".$qrCodeUrl."\n\n"; //Google Charts接口 生成的二维码图片,方便手机端扫描绑定安全密匙SecretKey=


$oneCode = $ga->getCode($secret); //服务端计算"一次性验证码"
echo "服务端计算的验证码是:".$oneCode."\n\n";
 
//把提交的验证码和服务端上生成的验证码做对比
// $secret 服务端的 "安全密匙SecretKey"
// $oneCode 手机上看到的 "一次性验证码"
// 最后一个参数 为容差时间,这里是2 那么就是 2* 30 sec 一分钟.
// 这里改成自己的业务逻辑

$code = '1';
 
$checkResult = $ga->verifyCode($secret, $code, 1);
if ($checkResult) {
    echo '匹配! OK';
} else {
    echo '不匹配! FAILED';
}

新建php文件:google.php

<?php 
class PHPGangsta_GoogleAuthenticator
{
    protected $_codeLength = 6;
 
    /**
     * Create new secret.
     * 16 characters, randomly chosen from the allowed base32 characters.
     *
     * @param int $secretLength
     *
     * @return string
     */
    public function createSecret($secretLength = 16)
    {
        $validChars = $this->_getBase32LookupTable();
 
        // Valid secret lengths are 80 to 640 bits
        if ($secretLength < 16 || $secretLength > 128) {
            throw new Exception('Bad secret length');
        }
        $secret = '';
        $rnd = false;
        if (function_exists('random_bytes')) {
            $rnd = random_bytes($secretLength);
        } elseif (function_exists('mcrypt_create_iv')) {
            $rnd = mcrypt_create_iv($secretLength, MCRYPT_DEV_URANDOM);
        } elseif (function_exists('openssl_random_pseudo_bytes')) {
            $rnd = openssl_random_pseudo_bytes($secretLength, $cryptoStrong);
            if (!$cryptoStrong) {
                $rnd = false;
            }
        }
        if ($rnd !== false) {
            for ($i = 0; $i < $secretLength; ++$i) {
                $secret .= $validChars[ord($rnd[$i]) & 31];
            }
        } else {
            throw new Exception('No source of secure random');
        }
 
        return $secret;
    }
 
    /**
     * Calculate the code, with given secret and point in time.
     *
     * @param string   $secret
     * @param int|null $timeSlice
     *
     * @return string
     */
    public function getCode($secret, $timeSlice = null)
    {
        if ($timeSlice === null) {
            $timeSlice = floor(time() / 30);
        }
 
        $secretkey = $this->_base32Decode($secret);
 
        // Pack time into binary string
        $time = chr(0).chr(0).chr(0).chr(0).pack('N*', $timeSlice);
        // Hash it with users secret key
        $hm = hash_hmac('SHA1', $time, $secretkey, true);
        // Use last nipple of result as index/offset
        $offset = ord(substr($hm, -1)) & 0x0F;
        // grab 4 bytes of the result
        $hashpart = substr($hm, $offset, 4);
 
        // Unpak binary value
        $value = unpack('N', $hashpart);
        $value = $value[1];
        // Only 32 bits
        $value = $value & 0x7FFFFFFF;
 
        $modulo = pow(10, $this->_codeLength);
 
        return str_pad($value % $modulo, $this->_codeLength, '0', STR_PAD_LEFT);
    }
 
    /**
     * Get QR-Code URL for image, from google charts.
     *
     * @param string $name
     * @param string $secret
     * @param string $title
     * @param array  $params
     *
     * @return string
     */
    public function getQRCodeGoogleUrl($name, $secret, $title = null, $params = array())
    {
        $width = !empty($params['width']) && (int) $params['width'] > 0 ? (int) $params['width'] : 200;
        $height = !empty($params['height']) && (int) $params['height'] > 0 ? (int) $params['height'] : 200;
        $level = !empty($params['level']) && array_search($params['level'], array('L', 'M', 'Q', 'H')) !== false ? $params['level'] : 'M';
 
        $urlencoded = urlencode('otpauth://totp/'.$name.'?secret='.$secret.'');
        if (isset($title)) {
            $urlencoded .= urlencode('&issuer='.urlencode($title));
        }
 
        return 'https://chart.googleapis.com/chart?chs='.$width.'x'.$height.'&chld='.$level.'|0&cht=qr&chl='.$urlencoded.'';
    }
 
    /**
     * Check if the code is correct. This will accept codes starting from $discrepancy*30sec ago to $discrepancy*30sec from now.
     *
     * @param string   $secret
     * @param string   $code
     * @param int      $discrepancy      This is the allowed time drift in 30 second units (8 means 4 minutes before or after)
     * @param int|null $currentTimeSlice time slice if we want use other that time()
     *
     * @return bool
     */
    public function verifyCode($secret, $code, $discrepancy = 1, $currentTimeSlice = null)
    {
        if ($currentTimeSlice === null) {
            $currentTimeSlice = floor(time() / 30);
        }
 
        if (strlen($code) != 6) {
            return false;
        }
 
        for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
            $calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);
            if ($this->timingSafeEquals($calculatedCode, $code)) {
                return true;
            }
        }
 
        return false;
    }
 
    /**
     * Set the code length, should be >=6.
     *
     * @param int $length
     *
     * @return PHPGangsta_GoogleAuthenticator
     */
    public function setCodeLength($length)
    {
        $this->_codeLength = $length;
 
        return $this;
    }
 
    /**
     * Helper class to decode base32.
     *
     * @param $secret
     *
     * @return bool|string
     */
    protected function _base32Decode($secret)
    {
        if (empty($secret)) {
            return '';
        }
 
        $base32chars = $this->_getBase32LookupTable();
        $base32charsFlipped = array_flip($base32chars);
 
        $paddingCharCount = substr_count($secret, $base32chars[32]);
        $allowedValues = array(6, 4, 3, 1, 0);
        if (!in_array($paddingCharCount, $allowedValues)) {
            return false;
        }
        for ($i = 0; $i < 4; ++$i) {
            if ($paddingCharCount == $allowedValues[$i] &&
                substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])) {
                return false;
            }
        }
        $secret = str_replace('=', '', $secret);
        $secret = str_split($secret);
        $binaryString = '';
        for ($i = 0; $i < count($secret); $i = $i + 8) {
            $x = '';
            if (!in_array($secret[$i], $base32chars)) {
                return false;
            }
            for ($j = 0; $j < 8; ++$j) {
                $x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
            }
            $eightBits = str_split($x, 8);
            for ($z = 0; $z < count($eightBits); ++$z) {
                $binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : '';
            }
        }
 
        return $binaryString;
    }
 
    /**
     * Get array with all 32 characters for decoding from/encoding to base32.
     *
     * @return array
     */
    protected function _getBase32LookupTable()
    {
        return array(
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', //  7
            'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
            'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
            '=',  // padding char
        );
    }
 
    /**
     * A timing safe equals comparison
     * more info here: http://blog.ircmaxell.com/2014/11/its-all-about-time.html.
     *
     * @param string $safeString The internal (safe) value to be checked
     * @param string $userString The user submitted (unsafe) value
     *
     * @return bool True if the two strings are identical
     */
    private function timingSafeEquals($safeString, $userString)
    {
        if (function_exists('hash_equals')) {
            return hash_equals($safeString, $userString);
        }
        $safeLen = strlen($safeString);
        $userLen = strlen($userString);
 
        if ($userLen != $safeLen) {
            return false;
        }
 
        $result = 0;
 
        for ($i = 0; $i < $userLen; ++$i) {
            $result |= (ord($safeString[$i]) ^ ord($userString[$i]));
        }
 
        // They are only identical strings if $result is exactly 0...
        return $result === 0;
    }
}
?>

访问demo.php开结果

获取访客(来访服务器)IP地址

function getIP() /*获取客户端IP*/ 
    { 
    if (@$_SERVER["HTTP_X_FORWARDED_FOR"]) 
    $ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; 
    else if (@$_SERVER["HTTP_CLIENT_IP"]) 
    $ip = $_SERVER["HTTP_CLIENT_IP"]; 
    else if (@$_SERVER["REMOTE_ADDR"]) 
    $ip = $_SERVER["REMOTE_ADDR"]; 
    else if (@getenv("HTTP_X_FORWARDED_FOR")) 
    $ip = getenv("HTTP_X_FORWARDED_FOR"); 
    else if (@getenv("HTTP_CLIENT_IP")) 
    $ip = getenv("HTTP_CLIENT_IP"); 
    else if (@getenv("REMOTE_ADDR")) 
    $ip = getenv("REMOTE_ADDR"); 
    else 
    $ip = "Unknown"; 
    return $ip; 
}

 

短信验证码获取等待60秒js

<script type="text/javascript">
/*-------------------------------------------*/
var InterValObj; //timer变量,控制时间
var count = 120; //间隔函数,1秒执行
var curCount;//当前剩余秒数
function sendMessage() {
    curCount = count;
    var phone=$("#phone1").val();//手机号码
	var code = $("#imgcode").val();
    if(phone != ""){
    //向后台发送处理数据
        $.ajax({
            type: "POST", //用POST方式传输
            dataType: "json", //数据格式:JSON
            url: '/api/sms.php', //目标地址
            data: {"phone":phone,'code':code},
			success: function(json){
	            if(json.status==1){
			        //设置button效果,开始计时
			        $("#btnSendCode").attr("disabled", "true");
			        $("#btnSendCode").val("请在" + curCount + "秒内输入验证码");
			        InterValObj = window.setInterval(SetRemainTime, 1000); //启动计时器,1秒执行一次
	                layer.msg('请注意查收');
	            }else{
					layer.msg(json.info);
				}
	        }
        });
    }else{
        layer.msg("手机号码不能为空!");
    }
}
//timer处理函数
function SetRemainTime() {
    if (curCount == 0) {
        window.clearInterval(InterValObj);//停止计时器
        $("#btnSendCode").removeAttr("disabled");//启用按钮
        $("#btnSendCode").val("重新发送验证码");
        code = ""; //清除验证码。如果不清除,过时间后,输入收到的验证码依然有效
    }
    else {
        curCount--;
        $("#btnSendCode").val("请在" + curCount + "秒内输入验证码");
    }
}
</script>

 

wordpress分页函数:the_posts_pagination

wordpress免插件分页,wordpress自带函数:the_posts_pagination

<?php the_posts_pagination( array(
'mid_size' => 3,
'prev_text' =>'上一页',
'next_text' =>'下一页',
'before_page_number' => '<span class="meta-nav screen-reader-text">第 </span>',
'after_page_number' => '<span class="meta-nav screen-reader-text"> 页</span>',
) ); ?>

利用wp_insert_post函数插入数据

在主题开发的过程中可能需要在前台提交数据到后台,比如前台投稿,项目提交等,这个使用利用wp_insert_post函数可以轻松搞定,下面我们来了解一下详细用法:

该函数可在数据库中插入文章及页面。如果$postarr参数有“ID”设置为一个值,那么文章将被更新。您可以通过设置“post_date”和“post_date_gmt”值来手动设置发布日期也可以通过设置“comment_status”值来关闭评论或打开注释。

使用方法

<?php wp_insert_post( array $postarr, bool $wp_error = false ); ?>

$postarr 参数说明

$postarr = array(
    'ID'                    => '0', // (int)默认值为0,如果是0以外的值,则该 ID 的文章将被更新。
    'post_author'           => get_current_user_id(), // (int)文章作者的ID,默认为当前登录的用户ID
    'post_date'             => '', // 文章发布时间,默认为当前时间。
    'post_date_gmt'         => '', // (字符串)GMT格式的文章发布时间。默认值是$post_date的值。
    'post_content'          => '', // (字符串)文章内容,默认为空。
    'post_content_filtered' => '', // (字符串)过滤后的内容,默认是空的。不要管这个,WordPress会自动处理。
    'post_title'            => '', // (字符串)文章标题,默认为空.
    'post_excerpt'          => '', // (字符串)文章摘要,默认为空。
    'post_status'           => '', // (字符串)文章状态,默认为『draft』,即草稿。
    'post_type'             => '', // (字符串)文章类型,默认为『post』.
    'comment_status'        => '', // (字符串)是否可以接受评论。接受『打开』或『关闭』。默认值是『default_comment_status』选项的值。
    'ping_status'           => '', // (字符串)是否可以接受ping命令。接受『打开』或『关闭』。默认值是『default_ping_status』选项的值。
    'post_password'         => '', // (字符串)访问该文章的密码,默认是空的。
    'post_name'             => '', // (字符串)文章的别名,当发布新的文章时会默认创建。
    'to_ping'               => '', // (字符串)空格或回车将url的列表分隔成ping,默认是空的。
    'pinged'                => '', // (字符串)空格或回车分隔的url列表,默认是空的。
    'post_modified'         => '', // (字符串)上次修改后的日期,默认是当前时间。
    'post_modified_gmt'     => '', // (字符串)最后在GMT时区修改后的日期,默认是当前时间。
    'post_parent'           => '', // (int)文章的父级文章ID,默认为 0。
    'menu_order'            => '', // (int)如果新文章为一个页面,可以设置一个页面序号,默认为 0。
    'post_mime_type'        => '', // (字符串)文章的mime类型,默认是空的。
    'guid'                  => '', // (字符串)全局唯一ID,用于引用post,默认是空的。
    'post_category'         => '', // (数组)文章分类目录,默认值为『default_category』选项的值。
    'tags_input'            => '', // (数组)文章标签,默认为空。
    'tax_input'             => '', // (数组)文章的自定义分类法项目,默认为空。
    'meta_input'            => '', // (数组)自定义字段,默认为空。
    'page_template'         => '', // 页面模板文件的名称,如,template.php,默认为空。
);

$wp_error

(可选)是否返回失败的WP_Error。

默认值:false

基本用法

// Create post object
$my_post = array(
  'post_title'    => wp_strip_all_tags( $_POST['post_title'] ),
  'post_content'  => $_POST['post_content'],
  'post_status'   => 'publish',
  'post_author'   => 1,
  'post_category' => array( 8,39 )
);
 
// Insert the post into the database
wp_insert_post( $my_post );

进阶插入到自定义分类法的文章和选择自定义分类法类别

$post_arr = array(
    'post_title'   => 'Test post',
    'post_content' => 'Test post content',
    'post_status'  => 'publish',
    'post_author'  => get_current_user_id(),
    'tax_input'    => array(
        'diy'     => '1',
    ),
    'meta_input'   => array(
        'test_meta_key' => 'value of test_meta_key',
    ),
);

diy是自定义分类法的方法,1是对应的ID

调用wordpress编辑器

<?php wp_editor( $content, $editor_id, $settings = array() ); ?>

参数说明

$content (string) (required) 编辑器的初始内容。
Default: None

$editor_id (string) (required) 文本区域和tinymce的html id属性值。只能包含小写字母和下划线。连字符会导致编辑器显示不正确。
Default: None

$settings (array) (optional) 参数数组。
Default: array()

Argumentswpautop (boolean) (optional) 是否使用wpautop添加段落。请注意,当wpautop为false时,将自动添加段落。
Default: true

media_buttons (boolean) (optional) 是否显示媒体插入/上载按钮
Default: true

textarea_name (string) (optional) 提交表单时分配给生成的文本区域和传递参数的名称。可以包含[]以将数据作为数组传递。)
Default: $editor_id

textarea_rows (integer) (optional) 为文本区域显示的行数
Default: get_option('default_post_edit_rows', 10)

tabindex (integer) (optional) 用于窗体字段的TabIndex值
Default: None

editor_css (string) (optional) 附加的CSS样式应用于视觉和HTML编辑器按钮,需要包括<style>标记,可以使用“范围”
Default: None

editor_class (string) (optional) 附加到编辑器文本区域的任何额外CSS类
Default: Empty string

editor_height (integer) (optional) 以像素为单位设置编辑器的高度。如果设置,将使用而不是文本区域\行。(从WordPress 3.5开始)
Default: None

teeny (boolean) (optional) 是否输出PressThis中使用的最小编辑器配置
Default: false

dfw (boolean) (optional) 无论是默认的全屏编辑器与DFW replace。CSS和DOM元素的空间特异性。
Default: false

tinymce (array) (optional) 加载tinymce,可用于使用数组将设置直接传递给tinymce
Default: true

quicktags (array) (optional) 加载快速标记,可用于使用数组将设置直接传递给快速标记。设置为false可删除编辑器的视觉和文本选项卡。
Default: true

drag_drop_upload (boolean) (optional) 启用拖放上载支持(从WordPress 3.9开始)
Default: false

参数说明

使用默认设置显示空编辑器:

<?php

$content = '';
$editor_id = 'mycustomeditor';

wp_editor( $content, $editor_id );

?>

用特定文章的内容填充编辑器:

<?php

$post_id = 51;
$post = get_post( $post_id, OBJECT, 'edit' );

$content = $post->post_content;
$editor_id = 'editpost';

wp_editor( $content, $editor_id );

?>

如果默认值不适合我们的需要,我们还可以传递一个或多个设置的数组。例如,如果我们想隐藏“插入媒体”按钮,我们可以这样做:

<?php

$settings = array( 'media_buttons' => false );

wp_editor( $content, $editor_id, $settings );

?>

我们还可以使用自定义按钮列表(包括自定义快速标记列表)修改默认的快速标记。

<?php

$settings = array( 
	'quicktags' => array( 'buttons' => 'strong,em,del,ul,ol,li,close' ), // note that spaces in this list seem to cause an issue
);

wp_editor( $content, $editor_id, $settings );

?>

请注意,传递给wp_editor()函数的ID只能由小写字母组成。没有下划线,没有连字符。其他任何事情都会导致WYSIWYG编辑器出现故障。(从3.6.1开始,您可以在ID中使用下划线。)
一旦实例化,所见即所得编辑器就不能在DOM中移动。从实际意义上讲,这意味着你不能把它放在元框中,而元框可以被拖放到页面的其他地方。相反,使用“编辑页面”或“编辑表单”高级(对于其他帖子类型):

add_action( 'edit_page_form', 'my_second_editor' );
function my_second_editor() {
	// get and set $content somehow...
	wp_editor( $content, 'mysecondeditor' );
}

 

利用update_user_meta()函数增加修改wordpress用户个人信息

在开发过程中我们需要对用户信息额外的字段进行更新和修改,或者增加,利用一些wordpress内置的函数就可以轻松完成:

update_user_meta( int $user_id, string $meta_key, mixed $meta_value, mixed $prev_value = '' )

顺序分别是:用户ID,字段名称,字段值

用此方法可以完成wordpress用户自定义字段的更新和增加修改

获取用户自定义字段值的方法是:

get_user_meta( int $user_id, string $key = '', bool $single = false )

顺序分别是:用户ID,字段名称