重启php-fpm如果进程意外死掉

#!/bin/sh
# */5 * * * * /var/www/php.sh >>  /var/www/php.log

php_fpm_count=$(ps aux | grep php-fpm | wc -l)
echo "php_fpm_count is $php_fpm_count"

if [ $php_fpm_count -lt 2 ]; then
    echo "Sorry, we have a problem with php-fpm! restart it"
    service php7.2-fpm restart
    chmod -R 777 /run/php # 如果使用sock,确保sock有执行权限
fi

*/5 * * * * /var/www/php.sh >> /var/www/php.log

放到 任务计划里,每5分钟执行一次。

Nginx For WordPress

##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";

gzip_vary on;
gzip_proxied any;
# 大于 4 之后,压缩大小几乎没有变化
gzip_comp_level 4;
gzip_http_version 1.1;
## 小于256B的不要压缩,默认是 20,太小了
gzip_min_length 256;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

server {
        listen      80;
        server_name docker.local;
        root        /var/www/html;
        index       index.php index.html;

        # 加上 * 不会去检查确切的 conf,如果文件不存在,一样可以通过 nginx 测试
        include /var/www/html/nginx.conf*;

        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }

        location = /xmlrpc.php {
                deny all;
                access_log off;
                log_not_found off;
        }

        location / {

                #禁止指定 user_agent 及 user_agent 为空的访问
                if ($http_user_agent ~ "FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|CoolpadWebkit|Java|Feedly|UniversalFeedParser|YandexBot|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|YisouSpider|HttpClient|MJ12bot|heritrix|EasouSpider|LinkpadBot|Ezooms|^$" )
                {
                        return 403;
                }

                # This is cool because no php is touched for static content.
                # include the "?$args" part so non-default permalinks doesn't break when using query string
                try_files $uri $uri/ /index.php?$args;
        }

        location ~ \.php$ {
                #include snippets/fastcgi-php.conf;
                #fastcgi_pass docker-php-fpm:9000;
                fastcgi_pass php-fpm:9000;
                include fastcgi_params;
                fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }
}

PHP multi-dimensional array sort

From: http://php.net/manual/en/function.usort.php

Example #4 usort() example using a closure to sort a multi-dimensional array

<?php
$array[0] = array('key_a' => 'z', 'key_b' => 'c');
$array[1] = array('key_a' => 'x', 'key_b' => 'b');
$array[2] = array('key_a' => 'y', 'key_b' => 'a');

function build_sorter($key) {
    return function ($a, $b) use ($key) {
        return strnatcmp($a[$key], $b[$key]);
    };
}

usort($array, build_sorter('key_b'));

foreach ($array as $item) {
    echo $item['key_a'] . ', ' . $item['key_b'] . "\n";
}
?>
The above example will output:
y, a
x, b
z, c

You can also sort multi-dimensional array for multiple values like as:

<?php
$arr = array(
    array('id'=>1, 'age'=>1, 'sex'=>6, 'name'=>'a'),
    array('id'=>2, 'age'=>3, 'sex'=>1, 'name'=>'c'),
    array('id'=>3, 'age'=>3, 'sex'=>1, 'name'=>'b'),
    array('id'=>4, 'age'=>2, 'sex'=>1, 'name'=>'d'),
);

print_r(arrayOrderBy($arr, 'age asc,sex asc,name desc'));

function arrayOrderBy(array &$arr, $order = null) {
    if (is_null($order)) {
        return $arr;
    }
    $orders = explode(',', $order);
    usort($arr, function($a, $b) use($orders) {
        $result = array();
        foreach ($orders as $value) {
            list($field, $sort) = array_map('trim', explode(' ', trim($value)));
            if (!(isset($a[$field]) && isset($b[$field]))) {
                continue;
            }
            if (strcasecmp($sort, 'desc') === 0) {
                $tmp = $a;
                $a = $b;
                $b = $tmp;
            }
            if (is_numeric($a[$field]) && is_numeric($b[$field]) ) {
                $result[] = $a[$field] - $b[$field];
            } else {
                $result[] = strcmp($a[$field], $b[$field]);
            }
        }
        return implode('', $result);
    });
    return $arr;
}
?>

output:
Array
(
    [0] => Array
        (
            [id] => 1
            [age] => 1
            [sex] => 6
            [name] => a
        )

    [1] => Array
        (
            [id] => 4
            [age] => 2
            [sex] => 1
            [name] => d
        )

    [2] => Array
        (
            [id] => 2
            [age] => 3
            [sex] => 1
            [name] => c
        )

    [3] => Array
        (
            [id] => 3
            [age] => 3
            [sex] => 1
            [name] => b
        )

)

Vue: Using localStorage with Vuex store

This tutorial uses Vue v2.4.4 and Vuex v2.5.0 – although I’m sure it will work with previous versions

localStorage basics#

localStorage is a cache in the browser which persists even after the browser is closed. It allows you to store data on a page and later access it – it’s especially easy to do using JavaScript. More information about localStorage can be found on the MDN Website, but the basics are as follows. The key is an identifiable string for you to access the saved data later.

// Store the "value" under the ID of "key"
localStorage.setItem('key', 'value');

// Load the data back and store as a variable
let val = localStorage.getItem('key');
// val will equal "value"

Note:

localStorage can only contain strings. This means that any objects or arrays you wish to store in localStorage must be converted to a JSON string, and then re-formatted when you retrieve them.

For example:

 // Convert the object into a JSON string and store
localStorage.setItem('key', JSON.stringify(object));

// Retrieve the data and convert from JSOn string to object/array
let obj = JSON.parse(localStorage.getItem('key'));

Vuex#

Vuex is a centralised state management tool for Vue. It gives you a central store that all of your components can access, update and react to changes. Unless you are doing a very simple (in functionality) Vue app, it is highly recommended you use Vuex for all of the management of your data and states.

Using localStorage with Vuex#

On the latest Vue app I’m developing, I wanted the Vuex contents (or state) to be stored in localStorage whenever it was updated. This meant that at any time the user could close their browser and, when they return, have the app in the same state as when they left it. Be it products in the basket or user preferences, I wanted the app to remember what they had chosen.

Initialise the store#

If you’re reading this I would assume you’ve got your store already initialised. However you’ve built your app, the store should have a variable assigned to it.

// Initialise your store
const store new Vuex.Store({
	// You state might be more complex than this
	state: {
		count: 1
	},
	mutations: {},
	getters: {}
});

Storing data#

We now wish to cache the data whenever the store updated. Fortunately, Vuex offers a subscribefunction which triggers whenever the store updates.

After your store has been initialised, register the subscribe method on your store variable. This function accepts two parameters – the mutation which was fired and the state after the mutation. We wish to store this state in our localStorage. As localStorage is specific to each domain name, we can use a variable name to reference the contents – such as store. Don’t forget to convert your object to a string.

// Subscribe to store updates
store.subscribe((mutation, state) => {
	// Store the state object as a JSON string
	localStorage.setItem('store', JSON.stringify(state));
});

Retrieving data#

With our data now stored with every update, we need to retrieve the data on page load. When the user re-accesses the app, we need to replace the existing, empty store with the contents of our storage.

To do this, we are going to create a mutation within the store, which updates the state, and trigger this when the app is created.

Create a new mutation called initialiseStore. Inside this mutation, check if the localStorageitem exists

const store new Vuex.Store({
	state: {
		count: 1
	},
	mutations: {
		initialiseStore(state) {
			// Check if the ID exists
			if(localStorage.getItem('store')) {
				
			}
		}
	},
	getters: {}
});

We now need to replace the current state if it does exist. To do this, we are going to use the replaceState Vuex method. Within here, we are going to merge both the current, blank, state and the stored data. The reason for this is so that if there are any new properties which were added since the last time the user visited, they don’t get any dreaded undefined errors.

const store new Vuex.Store({
	state: {
		count: 1
	},
	mutations: {
		initialiseStore(state) {
			// Check if the ID exists
			if(localStorage.getItem('store')) {
				// Replace the state object with the stored item
				this.replaceState(
					Object.assign(state, JSON.parse(localStorage.getItem('store')))
				);
			}
		}
	},
	getters: {}
});

The last stage is to call this mutation when the Vue app is created. We want this to happen at the earliestpoint which, based on the Vue lifecycle hooks is during the beforeCreate() method.

Add this method to your Vue instance and trigger the mutation:

new Vue({
	el: '#app',

	store,

	beforeCreate() {
		this.$store.commit('initialiseStore');
	}
});

Huzzah! You now have an app with a Vuex store cached in localStorage.


Update 20/10/17

Cache Validity#

While using this in a project recently, I experienced an odd sensation where changes I made were not being reflected. This is because I had altered the store structure without clearing my localStorage. Adding values was fine, but renaming, editing or altering a value’s type did not change.

Although not an issue for me, as I can clear the cache, if some code were to be pushed live, this could affect users who had visited the site before.

Fortunately, I was using semver for my versioning (and even if you’re not – this will work as long as you version each release somehow) and so I could call upon ver version number to check if the store was up to date.

If on load, the user had the same version number as that of my app, then the cache was fine. If it’s different, clear the cache and load a new version.

Be warned This will clear the whole cache, so if you are relying on it for user preferences or similar, you may wish to do the selective deletion.

The first step is to load our version number. Ours is stored in the package.json so, using ES6, this is as simple as:

import {version} from './package.json';

However, you may wish to cache yours from a git tag or have it somewhere as a variable. Ideally, it needs to be accessed separately from the store so that the cache doesn’t end up overwriting it.

Next, create an empty string in your store – for the version to be saved once verified.

state: {
	// Cache version
	version: '',
	count: 1
},

We can now update our initialiseStore mutation to check the version with that of the one in the cache and take appropriate action based on the result

initialiseStore(state) {
	// Check if the store exists
	if(localStorage.getItem('store')) {
		let store = JSON.parse(localStorage.getItem('store'));
		
		// Check the version stored against current. If different, don't
		// load the cached version
		if(store.version == version) {
			this.replaceState(
				Object.assign(state, store)
			);
		} else {
			state.version = version;
		}
	}
}

Update 25/10/17

Selective Caching#

You may only wish to cache a few elements from your store, this can be achieved by creating a new object in your subscribe function and storing that. We are already merging the cache with the current store state on load, so that doesn’t need to change.

store.subscribe((mutation, state) => {
	let store = {
		version: state.version,
		count: 1
	};

	localStorage.setItem('store', JSON.stringify(store));
});

自除数

自除数 是指可以被它包含的每一位数除尽的数。

例如,128 是一个自除数,因为 128 % 1 == 0128 % 2 == 0128 % 8 == 0

还有,自除数不允许包含 0 。

给定上边界和下边界数字,输出一个列表,列表的元素是边界(含边界)内所有的自除数。

输入: 
上边界left = 1, 下边界right = 22
输出: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22]

<script>

    /**
     * @param {number} left
     * @param {number} right
     * @return {number[]}
     */
    var selfDividingNumbers = function(left, right) {

        var dividing_numbers = [];

        function init(){
            for(number = left; number <= right; number ++ ){

                if(is_dividing_number(number)){
                    dividing_numbers.push(number);
                }
            }
            console.log(dividing_numbers)
        }

        function is_dividing_number(number){

            if(number.toString().indexOf('0') > 0){
                return false;
            }

            if(number < 10){
                return true;
            } else {
                var number_array = number.toString().split(''),
                    status = 0
                number_array.forEach(function(divid_number) {
                    if( number % parseInt(divid_number) > 0 ){
                        status++
                    }
                });

                if(status > 0 ){
                    return false;
                } else {
                    return true;
                }
            }
        }
        init();
    };

    selfDividingNumbers(127, 128)

</script>

创业公司根本不需要管理

本文由PMCAFF 产品经理社区原创专栏作者@ 马云龙 原创,转载请标明出处。

一说到管理,在我们的潜意识里面往往都是行政权利,都是生杀大权,都是威风凛凛,那我们就来分析下管理的本质,创业公司是否需要管理。

什么是管理

管理有很多种解释,比较容易理解的是:管理是由计划、组织、指挥、协调及控制等职能为要素组成的活动过程。

哪些事情需要管理

  1. 制定制度并维护
  2. 绩效考核与奖惩
  3. 职位升迁、招聘与辞退
  4. 公司的重要信息

下面来分析下需要管理的事情是否可以让团队自己完成。

一、制定制度并维护

为什么需要制定制度?

制度其实就是大家共同遵守的办事规程与行动准则,在这样一个 高度依赖协作 的社会里,制度确实是不可或缺,是每一个团队能高效运作的基础。

为什么需要管理?

管理能生成制度

管理能维护制度

不用管理是否可行?

制度的本质是约束,约束的初衷是限制人的惰性,但约束是外驱,人的本性是趋利避害,约束越多,越会增加人的反抗意识,越会限制人的创造力和积极性;所以道家的无为之治,反倒能有更好的效果,只要做到下面几点就可行:

  1. 只招个人目标与公司目标一致的人:只为做成一件事情(让自我实现战胜懒惰)
  2. 只招能高效做事,有很强学习能力的人
  3. 全员持股,全员决策
  4. 让员工和创始人一样,成为真正的主人
  5. 制度能少则少,少到没有为止

二、绩效考核与奖惩

绩效考核主要有考勤、KPI 等,而奖惩无外乎就是奖金、罚款;期权、股权、升职或辞退。

为什么需要绩效考核与奖惩?

为了激励大家更好的工作

也为了惩戒懒散的人

为什么需要管理?

管理能了解每个成员的工作情况;

管理能做到公平公正;

不用管理是否可行?

可行

  1. 设立项目奖金、设定期限与审核标准;
  2. 协作的员工互相背书、相互考评;
  3. 团队自己协商责任与应得奖励;

三、职位升迁、招聘与辞退

为什么需要职位升迁、招聘与辞退?

团队需要自我完善

团队需要优胜劣汰、新陈代新

团队需要更新血液、增强竞争力

为什么需要管理?

管理能更准确的掌握每个人的工作价值;

管理能知道团队的长处与短板;

管理能清楚每个人的工作表现与潜力;

不用管理是否可行?

可行

  1. 扁平化,减少层级结构,提高沟通效率,免去职位本身无意义的附加值
  2. 团队自己更清楚缺什么岗位、谁不称职,可以自我修复与成长

四、公司的重要信息

公司有哪些重要信息?

商业机密

战略上的坏消息

为什么需要管理?

管理能更好的保密

管理能挡住坏消息

不用管理是否可行?

可行

  1. 创业公司一般没有什么杀手锏级的绝密信息;
  2. 让员工知道所有实情,才能更好的培养员工的主人翁意识;
  3. 即使最坏的结果是团队解散,那早解散也比拖着好;

当然,上面这些不需要管理的分析都是有前提条件的:

  1. 创业公司或者有创业精神的公司(不适合 BAT)
  2. 团队成员有强烈的自我实现欲望
  3. 团队成员不斤斤计较、不痴迷权利
  4. 团队成员能安排好工作与生活

相信团队内驱要远胜于生硬的管理,就像一个人每件事情都要经过大脑理性分析,把指令发送给身体、然后再去实施,可能给你一天时间,你也走不出你们家小区的门。(潜意识和身体各个部位每天会帮大脑做无数决策)

最后,希望管理越来越少,制度越来越少;希望人性本身成为管理,人性本身之间的竞争成为制度。

原创文章,作者:PMCAFF产品社区,如若转载,请注明出处:http://36kr.com/p/5042772.html

在WordPress Feeds 里加入特色图片

编辑你的Feed模板基本与编辑你的主题模板一样。然而,Feed模板不集成到WordPress主题系统;如果你希望你的订阅的不同版本,你需要创建额外的模板。

自定义Feed模板

feed 模板位于/wp-includes/feed-{type}.php文件, 包括rdf格式、rss、rss和atom。他们是由feed重写规则使用一系列的行动中定义wp-includes /功能。使用 add_action wp-includes / default-filters.php php和附加。

为了覆盖需要清楚自己的模板默认行为叫load_template然后采取适当的步骤。使用一个模板为默认的一个示例rss2 feed 位于模板目录为自定义文章类型:

remove_all_actions( 'do_feed_rss2' );
add_action( 'do_feed_rss2', 'itc_feed_rss2', 10, 1 );

function itc_feed_rss2( $for_comments ) {
	$rss_template = get_template_directory() . '/feeds/itc_feed_rss2.php';
	if(get_query_var( 'post_type' ) == 'post' && file_exists( $rss_template ) )
		load_template( $rss_template );
	else
		do_feed_rss2( $for_comments ); // Call default function
}

然后在你的主题里建立一个feeds 目录,新建一个rss2 文件叫: itc_feed_rss2.php

复制 /wp-includes/feed-rss2.php 里的代码到 itc_feed_rss2.php

然后在<item> 里面加一段代码来插入特色图片,例如

	<item>
		<title><?php the_title_rss() ?></title>
		<link><?php the_permalink_rss() ?></link>
		<?php 
		if ( has_post_thumbnail() ) {
			$large_image_url = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), 'full' ); 
			echo '<image>' . $large_image_url[0] . '</image>'; 
		}
		?> 
		<comments><?php comments_link_feed(); ?></comments>

 

WordPress 获取相关文章

或许有点用,不过只适用与文章类型。

设想是:

  1. 首先获取拥有相同标贴的文章
  2. 如果数量不足,获取拥有部分相同标签的文章
  3. 如果数量还不足,获取拥有相同分类的文章
  4. 再不足,获取部分相同分类的文章

代码大致:

/*
 * class itcGetRelatedPosts
 * get related post by tags and categories
 * $related_posts = new itcGetRelatedPosts($post_id, 3);
 * */

class itcGetRelatedPosts {

	protected $_date;

	public function __construct($post_id, $showposts){
		$this->setDefault($post_id, $showposts);
		$this->_getPosts();
	}

	protected function setDefault($post_id, $showposts){
		$this->_date['post_id']			= $post_id;
		$this->_date['exclude_ids'][] 	= $post_id;
		$this->_date['showposts']		= $showposts;
		$this->_date['args']['post_type']	= 'post';
		$this->_date['posts']	= array();
		$this->_date['post_count']	= 0;
		$this->_getTagIds();
		$this->_updateArgs();
	}

	protected function _updateArgs(){
		$this->_date['args']['post__not_in']	= $this->_date['exclude_ids'];
		$this->_date['args']['posts_per_page']	= $this->_date['showposts'] - $this->_date['post_count'];
	}

	protected function _getTagIds(){
		$posttags = get_the_tags($this->_date['post_id']);
		if ($posttags) {
			foreach($posttags as $tag) {
				$this->_date['tag_ids'][] = $tag->term_id;
			}
		}else{
			$this->_date['tag_ids'] = NULL;
		}
	}

	protected function _getCategoryIds(){
		$categories = get_the_category($this->_date['post_id']);
		if($categories){
			foreach($categories as $category) {
				$this->_date['category_ids'][] = $category->term_id;
			}
		}else{ 
			$this->_date['category_ids'] = NULL;
		}
	}

	protected function _getPosts(){
		if($this->_date['tag_ids'] != NULL){
			//Display posts that are tagged with both tag id 37 and tag id 47
			$this->_date['args']['tag__and'] = $this->_date['tag_ids'];
			$this->_pushPost($this->_date['args']);
				
			//To display posts from either tag id 37 or 47
			if($this->_date['post_count'] < $this->_date['showposts']){
				unset($this->_date['args']['tag__and']);
				$this->_date['args']['tag__in'] = $this->_date['tag_ids'];
				$this->_pushPost($this->_date['args']);
			}
		}

		if($this->_date['post_count'] < $this->_date['showposts']){
			$this->_getCategoryIds();
			if(isset($this->_date['args']['tag__and'])) unset($this->_date['args']['tag__and']);
			if(isset($this->_date['args']['tag__in'])) unset($this->_date['args']['tag__in']);
			//Display posts that are in multiple categories. This shows posts that are in both categories 2 and 6:
			$this->_date['args']['category__and'] = $this->_date['category_ids'];
			$this->_pushPost($this->_date['args']);
		}
		//To display posts from either category 2 OR 6
		if($this->_date['post_count'] < $this->_date['showposts']){
			unset($this->_date['args']['category__and']);
			$this->_date['args']['category__in'] = $this->_date['category_ids'];
			$this->_pushPost($this->_date['args']);
		}
	}

	protected function _pushPost($the_args){
		$the_query = new WP_Query($the_args);
		if ( $the_query->have_posts() ) {
			$this->_date['post_count'] = $this->_date['post_count'] + $the_query->post_count;
			while ( $the_query->have_posts() ) { 
				$the_query->the_post();
				$this->_date['exclude_ids'][] = get_the_ID();
				$this->_date['posts'][get_the_ID()] = array(
						'ID' => get_the_ID(),
						'title' => get_the_title(),
						'link'	=> get_permalink(),
						//'format'	=> get_label_format(get_the_ID()),
						'excerpt'	=> get_the_excerpt()
				);
				$this->_date['posts'][get_the_ID()]['date'] = get_the_date(__('F j, Y'));
			}
			$this->_updateArgs();
		}
		wp_reset_postdata();
	}

	public function getPosts(){
		return $this->_date['posts'];
	}

	public function get_date(){
		print_r($this->_date);
	}
}

 

 

WordPress 如何在 Child Theme 重写 Parent 里的 shortcode

很多时候客户选择去购买商业主题来建站,很多商业主题都做得很不错,功能也很完善,但是肯定不是100%客户想要的,有些功能还是要修改的。

对于这种商业主题,作者会不定期更新,所以修改原主题就不是一个很好的解决办法,一般做法是新建一个 child theme 来重写一些功能。

那问题就来了,如何重写 shortcode 呢?方法如下

function itc_shortcodes() {
    remove_shortcode( 'portfolio_slider' );
    add_shortcode( 'portfolio_slider', 'itc_portfolio_slider' );
}

function itc_portfolio_slider(){
    return "YAO";
}
add_action( 'init', 'itc_shortcodes' );

注:对于应该使用哪一个 action,要去夫主题查看一下,如果夫主题是用的 action wp, 那么最后一行就应该替换为

add_action( 'wp', 'itc_shortcodes' );

这样你只需要将原来的代码负责过来放到新的 shortcode 的函数里,修改即可。