0%

我相信,梦里能到达的地方,总有一天,脚步也能到达。

css文件位置

hexo\blog\themes\next\source\css\_custom\custom.styl

1
2
3
4
5
6
7
8
9
10
11
// Custom styles.
#header {
background:url(/images/header.jpg);
background-repeat: no-repeat;
background-size: cover;
color: #fff !important;
}

#menu a{
color: #c9c9c9 !important;
}

图片文件位置

hexo\blog\themes\next\source\images
可以在该目录下添加主题所需要的图片

如果上传不生效请尝试

1
2
3
4
5
step1: hexo clean (请尝试, 一般无需执行)
step2: hexo s (检查是自己的更改是否成功)
step3: hexo g
step4: gulp (这是拓展项,需要安装gulp插件,如果没有,可以忽略)
step5: hexo d

https://syd192.github.io/2016/11/15/hexo-learn/

我要把我向往的风景,变成我走过的路。

TDK优化

TDK为title,description,keywords三个的统称。当然title是最有用的,是非常值得优化的;而keywords因为以前被seo人员过度使用,所以现在对这个进行优化对搜索引擎是没用的,这里就不说了;description的描述会直接显示在搜索的介绍中,所以对用户的判断是否点击还是非常有效的。

title优化

title的分隔符一般有, _ - 等,其中_对百度比较友好,而-对谷歌比较友好,第四个为空格,英文站点可以使用中文少用。title长度一般pc端大概30个中文,移动端20个,超过则会截断为省略号。

因为业务关系,我们做的更多的是针对百度搜索引擎的优化,所以这里把百度搜索引擎优化的建议分享下:

title格式:
首页:网站名称 或者 网站名称_提供服务介绍or产品介绍
频道页:频道名称_网站名称
文章页:文章title_频道名称_网站名称
如果你的文章标题不是很长,还可以加入点关键词进去,如文章title_关键词_网站名称

推荐做法:
每个网页应该有一个独一无二的标题,切忌所有的页面都使用同样的默认标题
标题要主题明确,包含这个网页中最重要的内容
简明精练,不罗列与网页内容不相关的信息
用户浏览通常是从左到右的,重要的内容应该放到title的靠前的位置
使用用户所熟知的语言描述。如果你有中、英文两种网站名称,尽量使用用户熟知的那一种做为标题描述

description优化

description不是权值计算的参考因素,这个标签存在与否不影响网页权值,只会用做搜索结果摘要的一个选择目标。其长度pc端大概为78个中文,移动端为50个,超过则会截断为省略号。

百度推荐做法为:
网站首页、频道页、产品参数页等没有大段文字可以用做摘要的网页最适合使用description
准确的描述网页,不要堆砌关键词
为每个网页创建不同的description,避免所有网页都使用同样的描述
长度合理,不过长不过短

页面内容优化

使用html5结构

果条件允许(如移动端,兼容ie9+,如果ie8+就针对ie8引入html5.js吧),是时候开始考虑使用html5语义化标签。如header,footer,section,aside,nav,article等

唯一的H1标题

每个页面都应该有个唯一的h1标题,但不是每个页面的h1标题都是站点名称。(但html5中h1标题是可以多次出现的,每个具有结构大纲的标签都可以拥有自己独立的h1标题,如header,footer,section,aside,article

首页的h1标题为站点名称,内页的h1标题为各个内页的标题,如分类页用分类的名字,详细页用详细页标题作为h1标题

1
2
3
4
5
6
<!-- 首页 -->
<h1 class="page-tt">腾讯课堂</h1>
<!-- 分类页 -->
<h1 class="page-tt">前端开发在线培训视频教程</h1>
<!-- 详细页 -->
<h1 class="page-tt">html5+CSS3</h1>

img设置alt属性

img必须设置alt属性,如果宽度和高度固定请同时设置固定的值

1
<img src="" alt="seo优化实战" width="200" height="100" />

nofollow

对不需要跟踪爬行的链接,设置nofollow。可用在博客评论、论坛帖子、社会化网站、留言板等地方,也可用于广告链接,还可用于隐私政策,用户条款,登录等。如下代码表示该链接不需要跟踪爬行,可以阻止蜘蛛爬行及传递权重。

1
<a href="http://example.com" rel="nofollow">no follow 链接</a>

正文

内容方面考虑:

  • 自然写作
  • 高质量原创内容
  • 吸引阅读的写作手法
  • 突出卖点
  • 增强信任感
  • 引导进一步行为

用户体验方面考虑:

  • 排版合理、清晰、美观、字体、背景易于阅读
  • 实质内容处在页面最重要位置,用户一眼就能看到
  • 实质内容与广告能够清晰区分
  • 第一屏就有实质内容,而不是需要下拉页面才能看到
  • 广告数量不宜过多,位置不应该妨碍用户阅读
  • 如果图片、视频有利于用户理解页面内容,尽量制作图片、视频等
  • 避免过多弹窗

URL优化

URL设计原则:

  • 越短越好
  • 避免太多参数
  • 目录层次尽量少
  • 文件及目录名具描述性
  • URL中包括关键词(中文除外)
  • 字母全部小写
  • 连词符使用-而不是_
  • 目录形式而非文件形式
  • URL静态化

以现在搜索引擎的爬行能力是可以不用做静态化的,但是从收录难易度,用户体验及社会化分享,静态简短的URL都是更有利的。

URL规范化

1、统一连接

1
2
3
4
http://www.domainname.com
http://domainname.com
http://www.domainname.com/index.html
http://domainname.com/index.html

以上四个其实都是首页,虽然不会给访客造成什么麻烦,但对于搜索引擎来说就是四条网址,并且内容相同,很可能会被误认为是作弊手段,而且当搜索引擎要规范化网址时,需要从这些选择当中挑一个最好的代表,但是挑的这个不一定是你想要的。所以最好自己就规范好。

2、301跳转
第一种是URL发生改变,一定要把旧的地址301指向新的,不然之前做的一些收录权重什么的全白搭了。

第二种是一些cms系统,极有可能会造成多个路径对应同一篇文章。如drupal默认的路径是以node/nid,但是如果启用了path token,就可以自己自定义路径。这样一来就有两条路径对应同一篇文章。所以可以启用301,最终转向一个路径。

3、canonical
这个标签表示页面的唯一性(这个标签以前百度不支持,现在支持),用在平时参数传递的时候,如:

1
2
3
//:ke.qq.com/download/app.html
//:ke.qq.com/download/app.html?from=123
//:ke.qq.com/download/app.html?from=456

以上三个表示三个页面,但其实后两个只是想表明从哪来的而已,所以为了确保这三个为同一个页面,我们在head上加上canonical标签。

1
<link rel="cononical" href="//:ke.qq.com/download/download/app.html" />

robots

搜索引擎蜘蛛访问网站时会第一个访问robots.txt文件,robots.txt用于指导搜索引擎蜘蛛禁止抓取网站某些内容或只允许抓取那些内容,放在站点根目录。
User-agent 表示以下规则适用哪个蜘蛛,*表示所有
#表示注释
Disallow 表示禁止抓取的文件或目录,必须每个一行,分开写
Allow 表示允许抓取的文件或目录,必须每个一行,分开写
Sitemap 表示站点XML地图,注意S大写

sitemap

站点地图格式分为HTML和XML两种。

HTML版本的是普通的HTML页面sitemap.html,用户可以直接访问,可以列出站点的所有主要链接,建议不超过100条。

XML版本的站点地图是google在2005年提出的,由XML标签组成,编码为utf-8,罗列页面所有的URL。其格式如下:

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>//ke.qq.com</loc>
<lastmod>2015-12-28</lastmod>
<changefreq>always</changefreq>
<priority>1.0</priority>
</url>
...
</urlset>

其中urlset,url,loc三个为必须标签,lastmod,changefreq,priority为可选标签。

lastmod表示页面最后一次更新时间。

changefreq表示文件更新频率,有以下几种取值:always, hourly, daily, weekly, monthly, yearly, never。其中always表示一直变动,每次访问页面内容都不同;而never表示从来不变。

priority表示URL相对重要程度,取值范围为0.0-1.0,1.0表示最重要,一般用在网站首页,对应的0.0就是最不重要的,默认重要程度为0.5。(注意这里的重要度是我们标记的,并不代表搜索引擎真的就完全按照我们设置的重要度来排列)

sitemap.xml不能超过10M,而且每个sitemap文件中url的条数不要超过5万条,当你的sitemap文件很大的时候,可以分解为多个文件。如下分为两条,一条为基础,一条为产品详细页。

1
2
3
4
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap><loc>//ke.qq.com/sitemap-basic.xml</loc><lastmod>2015-12-28T02:10Z</lastmod></sitemap>
<sitemap><loc>//ke.qq.com/sitemap-product.xml</loc><lastmod>2015-12-28T02:10Z</lastmod></sitemap>
</sitemapindex>

SEO工具

百度搜索风云榜
百度指数
百度站长平台
meta seo inspector,检查标签的,谷歌插件
seo in china,百度收录的各种数据,谷歌插件
check my links,检查链接,谷歌插件
seo quake,统计各种数据,谷歌插件

http://imweb.io/topic/5682938b57d7a6c47914fc00

你跑得慢,听到的是骂声,你跑得快,听到的就是风声。

禁止登录

app\Http\Controllers\Auth\LoginController.php
users表增加一个status字段,并重写两个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected function attemptLogin(Request $request)
{
$request->merge([
'status' => true
]);
return $this->guard()->attempt(
$this->credentials($request), $request->filled('remember')
);
}

protected function credentials(Request $request)
{
return $request->only($this->username(), 'password', 'status');
}

禁止注册

app\Http\Controllers\Auth\RegisterController.php
修改前:

1
2
3
4
public function __construct()
{
$this->middleware('guest');
}

修改后:

1
2
3
4
public function __construct()
{
$this->middleware('auth');
}

你多学一样本事,就少说一句求人的话
如果我们需要向我们的用用户展示一段`json`数据, 直接展示效果就会非常差,需要做一点点改变
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$("button").click(function () {
const url = $("input").val();
console.log(url);
axios.post('/api/E1WWrhcuN0xm', {
url : url
})
.then(function (response) {
if (response.data) {
console.log(response.data);
$("pre").html(JSON.stringify(response.data, null, 2)).parent().removeClass('hidden');
}
})
.catch(function (error) {
console.log(error);
});
});

酒贱常愁客少,月明多被云妨.

函数调用

第一种调用方式:

1
2
3
4
5
function test() {
echo 'test';
}

test();

第二种调用方式:

1
2
3
4
5
function test() {
echo 'test';
}

call_user_func('test');

参数传递:

1
2
3
4
5
6
function test($a, $b) {
echo $a;
echo $b;
}

call_user_func_array ('test', [1, 'ff']);

不定参数:

1
2
3
4
5
6
function oldAdd() {
$args = func_get_args();
dd($args);
}

oldAdd('1', '2', '3');

或者

1
2
3
4
5
6
function test() {
$args = func_get_args();
dd($args);
}

call_user_func_array ('test', [1, 'ff']);

方法调用

第一种方法:

1
2
3
4
5
6
7
8
9
class Test
{
public function hehe()
{
echo 'hehe';
}
}

(new Test())->hehe();

第二种方法:

1
2
3
4
5
6
7
8
9
10
class Test
{
public function hehe()
{
echo 'hehe';
}
}

$f = new Test();
call_user_func([ $f, 'hehe']);

静态方法:

1
2
3
4
5
6
7
8
9
class Test
{
public static function hehe($a, $b)
{
echo $a;
}
}

call_user_func_array([ 'Test', 'hehe'], ['we', 34]);

普通方法传递参数:

1
2
3
4
5
6
7
8
9
10
class Test
{
public function hehe($a, $b)
{
echo $a;
}
}

$f = new Test();
call_user_func_array([ $f, 'hehe'], ['we', 34]);

类内部的方法调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Test
{
public function hehe($a, $b)
{
call_user_func([$this, 'init']);
echo $a;
}

public function init()
{
echo '--init--';
}
}

$f = new Test();
call_user_func_array([ $f, 'hehe'], ['we', 34]);

两种调用的区别

call_user_func is for calling functions whose name you don’t know ahead of time but it is much less efficient since the program has to lookup the function at runtime.

奥巴马55岁就退休,川普70岁才开始当总统。
number_format() 函数格式化以后的数字不再是数字, 而是字符串
1
2
3
$num = 12.5345;
$format = number_format($num, 2);
dd(is_string($format)); // true
所以字符串0.00并不是false
1
2
3
$num = 0;
$format = number_format($num, 2);
dd(empty($format)); // false
数字0.00 才是false
1
dd(empty(0.00));  // true
还有一个字符串0是false
1
dump(empty('0'));  // true
而字符串0.0确是true
1
dump(empty('0.0'));  // false
字符串强制转化成数字
1
2
3
$num = 12.45;
$format = number_format($num, 2);
dd(floatval($format));

世人谓我恋长安,其实只恋长安某。
在使用curl上传POST一段数据时,被提示413 Request Entity Too Large,应该是nginx限制了上传数据的大小。 解决方法就是: 打开nginx主配置文件`nginx.conf`,一般在`/usr/local/nginx/conf/nginx.conf`这个位置,找到`http{}`段,修改或者添加
1
client_max_body_size 2m;
然后重启nginx,
1
sudo /etc/init.d/nginxd reload
即可。 要是以php运行的话,这个大小`client_max_body_size`要和`php.ini`中的如下值的最大值差不多或者稍大,这样就不会因为提交数据大小不一致出现错误。
1
2
post_max_size = 2M
upload_max_filesize = 2M

仓廪实而知礼节,衣食足而知荣辱

在依赖注入这一篇博客里, 我们在一个已有的AppServiceProvider(服务提供者)中做了一个简单的绑定
app\Providers\AppServiceProvider.php

1
2
3
4
5
6
7
use App\Repositories\UserRepository;
use App\Repositories\UserRepositoryInterFace;

public function register()
{
$this->app->bind(UserRepositoryInterFace::class, UserRepository::class);
}

现在我们创建一个自己的服务提供者

创建服务提供者

php artisan make:provider RepostiyServiceProvider
app\Providers\RepostiyServiceProvider.php

注册

config\app.php

1
2
3
4
'providers' => [
......
\App\Providers\RepostiyServiceProvider::class
],

接口和类的绑定

1
2
3
4
5
6
7
8
9
10
11
use App\Repositories\UserRepository;
use App\Repositories\UserRepositoryInterFace;
use Illuminate\Support\ServiceProvider;

class RepostiyServiceProvider extends ServiceProvider
{
.....
public function register()
{
$this->app->bind(UserRepositoryInterFace::class, UserRepository::class);
}

同样实现了上一篇博客的依赖注入
还可以这样绑定

1
2
3
4
5
6
7
public function register()
{
//$this->app->bind(UserRepositoryInterFace::class, UserRepository::class);
$this->app->bind('App\Repositories\UserRepositoryInterFace',function(){
return new UserRepository();
});
}

绑定单例

1
2
3
4
5
6
7
8
use App\Repositories\UserRepository;
public function register()
{
//使用singleton绑定单例
$this->app->singleton('test',function(){
return new UserRepository();
});
}

在HomeController.php中使用

1
2
3
4
5
public function index()
{
$test = \App::make('test');
$test->haha();
}

或者

1
2
3
4
5
public function index()
{
$test = app('test');
$test->haha();
}

绑定一个普通类

现在假设我们有一个特别功能的 FooService 类。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
namespace App\Services;
class FooService
{
public function __construct()
{
...
}
public function doSomething()
{
// Code for Something.
}
}

如果我们要调用类的 doSomething 方法,我们可能会这样做 :

1
2
$fooService = new \App\Services\FooService();
$fooService->doSomething();

这看起来没有什么问题,但比较麻烦的是这儿的 ‘new’ 关键字,我的意思是虽然这样也很好,但是我们可以做的更优雅 (记住写代码要像 Laravel 一样,用优雅的方式)。

如何绑定 ?
绑定简单得可以用一行代码完成

1
$this->app->bind('FooService', \App\Services\FooService::class);

使用

1
2
3
4
5
// 使用IoC 我们可以这么做
$fooService = app()->make('FooService');
$fooService->doSomething();
// 也可以精简为一行代码
app()->make('FooService')->doSomething();

https://laravel-china.org/topics/10273/laravel-service-container-must-know

世之奇伟、瑰怪、非常之观,常在于险远,而人之所罕至焉,故非有志者不能至也。

不是我自身的,却是我需要的,都是我所依赖的。一切需要外部提供的,都是需要进行依赖注入的。

依赖注入实现

女孩接口以及实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
//女孩接口
interface Girl {

}
//第一个女孩
class LoliGril implements Girl
{
public function __construct()
{
echo "LoliGril girl friend";
}
public function make()
{
echo "love LoliGril ";
}
}
//第二个女孩
class Vixen implements Girl {
public function __construct()
{
echo "Vixen girl friend";
}
public function make()
{
echo "love Vixen ";
}
}

男孩需要一个女朋友

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//男孩
class Boy {
protected $girl;
public function __construct(Girl $girl) {//这里Girl 请使用接口,而不是类,这样所有继承这个接口的类都可以注入
$this->girl = $girl;
}

public function yoyo()
{
$this->girl->make();
}
}

// 注意这里我们是实例化了对象之后在对象直接传递到构造方法中去,而在laravel中, 他会直接给我们提前实例化该接口绑定的对象
$loliGirl = new LoliGril();
//$vixen = new Vixen();

$boy = new Boy($loliGirl);
$boy->yoyo();

//$boy = new Boy($vixen);
?>

主动依赖和被动依赖

1
2
3
4
5
6
7
8
9
10
11
//主动依赖
function __construct()
{
$this->user=new UserModel();
}
//被动依赖
function __construct(UserModel $user)
{
$this->user=$user;
}

laravel依赖注入

新建一个类

app\Repositories\UserRepository.php

1
2
3
4
5
6
7
8
9
<?php
namespace App\Repositories;

class UserRepository {
public function haha()
{
echo 'text';
}
}

在HomeController中注入类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

namespace App\Http\Controllers;
use App\Repositories\UserRepository;

class HomeController extends Controller
{
protected $userRepository;

public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}

public function index()
{
$this->userRepository->haha();
}
}

以上代码可以直接运行

尝试注入接口,而不是类

新建一接口

app\Repositories\UserRepositoryInterFace.php

1
2
3
4
5
6
7
8
<?php
namespace App\Repositories;

interface UserRepositoryInterFace
{
public function haha();
public function hehe();
}

修改UserRepository.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
namespace App\Repositories;

class UserRepository implements UserRepositoryInterFace {
public function haha()
{
echo 'text';
}

public function hehe()
{
// TODO: Implement hehe() method.
}
}

在HomeController中注入接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
namespace App\Http\Controllers;

use App\Repositories\UserRepositoryInterFace;

class HomeController extends Controller
{
protected $userRepository;

public function __construct(UserRepositoryInterFace $userRepositoryInterFace)
{
$this->userRepository = $userRepositoryInterFace;
}

public function index()
{
$this->userRepository->haha();
}
}

绑定

我们依赖注入的是接口的时候, 需要做在AppServiceProvider(服务提供者)中做绑定,这样 laravel 就会帮你实例化依赖注入的类
app\Providers\AppServiceProvider.php

1
2
3
4
5
6
7
use App\Repositories\UserRepository;
use App\Repositories\UserRepositoryInterFace;

public function register()
{
$this->app->bind(UserRepositoryInterFace::class, UserRepository::class);
}