composer install 无法下载

如下图。

your configuration does not allow to connection to `http://xxxxxxx`,see the https://getcomposer.org/doc/06-config.md#secure-http for details.

按照提示打开 https://getcomposer.org/doc/06-config.md#secure-http

secure-http#

Defaults to true. If set to true only HTTPS URLs are allowed to be downloaded via Composer. If you really absolutely need HTTP access to something then you can disable it, but using Let's Encrypt to get a free SSL certificate is generally a better alternative.

默认是必须使用https的,而默认配置使用的镜像是http的。

所以,解决办法有两个,一个是,在本项目的composer.json 中添加 secure-http 配置:

  "config": {
    "secure-http": false
  }

composer的配置分为全局和各个项目的。针对当前项目是可以以第一种方式实现。而如果我们需要使用 composer 创建项目时当然不可行了。例如 composer create-project --prefer-dist laravel/lumen blog

于是第二个解决的办法就是在 composer 的全局配置文件 config.json 中添加 secure-http 配置。 在 win10 中这个配置文件位于 C:\Users\xxx\AppData\Roaming\Composer\config.json 中。

    "config": {
	    "secure-http": false
	},
    "repositories": {
        "packagist": {
            "type": "composer",
            "url": "http://packagist.phpcomposer.com"
        }
    }

参考资料


php include()和 require() 的区别说明

这也是个老生常谈的东西了,今天在阅读laravel的源代码,顺手记一下。

在php中引用文件有两种办法,require(_once) 及 include(_once)。

他们最主要的不同点在于

  • 使用include时,一般是放在流程控制的处理部分中。PHP 程序网页在读到 include 的文件时,才将它读进来。这种方式,可以把程序执行时的流程简单化。当包含的文件不存在时,系统会报出警告级别的错误(warning),程序会继续往下执行。
  • 使用require时,通常放在 PHP 程序的最前面,使得 PHP 程序在执行前,就会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部份。当包含的文件不存在时,系统会先报出警告级别的错误(warning),接着又报一个致命级别的错误(Fatal error)。程序终止执行。
  • incluce在用到时加载,require在一开始就加载,_once后缀表示已加载的不加载
  • require()通常来导入静态的内容,而include()则适合用导入动态的程序代码。

      对include()语句来说,在执行文件时每次都要进行读取和评估;
      而对于require()来说,文件只处理一次(实际上,文件内容替换require()语句)。
      这就意味着如果可能执行多次的代码,则使用require()效率比较高,如果每次执行代码时是读取不同的文件,或者有通过一组文件迭代的循环,就使用include()语句。
    
  • include有返回值,而require没有。

    例如laravel的index.php文件中通过 require_once 对 app 进行赋值:

      // index.php
          <?php
          require __DIR__.'/../bootstrap/autoload.php';
          $app = require_once __DIR__.'/../bootstrap/app.php';
    
      // app.php
    
          <?php
          $app = new Illuminate\Foundation\Application(
              realpath(__DIR__.'/../')
          );
            
          ...
    
          return $app;
    

参考资料


composer install update 报错需要 vendor autoload.php

先说一下背景。这些天在整一些laravel底层架构。今天composer update了某个包,报错。因为是实验性的,所以也没怎么注意,删掉vendor重新install一下呗。转念一想,顺便把composer.lock也重新构建一下吧。

然后。

就嗝屁了。

Warning: require(vendor/autoload.php): failed to open stream: No such file or directory in 

总之得出来的一个教训就是,composer.lock和vendor不能同时删除。

也找到了之前一个配置谜之被删的原因了:Remove-pre-update-cmd

参考资料


转载 | Alpine Linux,一个只有5M的Docker镜像

Alpine Linux Docker镜像基于Alpine Linux操作系统,后者是一个面向安全的轻型Linux发行版。不同于通常Linux发行版,Alpine Linux采用了musl libc和busybox以减小系统的体积和运行时资源消耗。在保持瘦身的同时,Alpine Linux还提供了自己的包管理工具apk,可以在其网站上查询,或者直接通过apk命令查询和安装。

Alpine Linux Docker镜像也继承了Alpine Linux发行版的这些优势。相比于其他Docker镜像,它的容量非常小,仅仅只有5M,且拥有非常友好的包管理器。

下表是一些官方镜像的大小:

镜像名称 大小(MB)
ubuntu:latest 187.9
debian:latest 125.1
centos:latest 196.6
alpine 4.794

除了小,Alpine镜像的另外一大优势就是内置完整包管理器。相较于其他微型基础镜像(如busybox,基础镜像大小为1.113MB),拥有一个包管理器,可以快速构建应用镜像。例如这个dnsmasq镜像,Dockerfile非常简单,仅仅运行了Alpine提供的apk工具安装了dnsmasq包即可:

FROM alpine:3.2
RUN apk -U add dnsmasq
EXPOSE 53 53/udp
ENTRYPOINT ["dnsmasq", "-k"]

使用

由于Alpine Linux有完整的包管理器,其使用方式和其他的基础镜像类似,直接使用其包管理命令apk即可。

如README中例子,如果需要安装一个mysql客户端,只需要创建如下Dockerfile:

FROM gliderlabs/alpine:3.3
RUN apk add --no-cache mysql-client
ENTRYPOINT ["mysql"]

然后通过docker build命令,即可构建出自己的mysql客户端。同样,基于Alpine Linux构建出来的镜像,有其空间上的巨大优势:

docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
alpine/mysql        latest              edf988b8f4c8        58 seconds ago      35.74 MB

争论

对于Alpine Linux,Hacker News上争论还是比较激烈的。

首先是空间占用问题,小是Alpine Linux的最大优势,但是Docker的文件系统可以进行分层缓存,对于已经构建或者拉取过镜像的机器来说,每次的增量更新内容可能并不会很多。也就是说,如果所有镜像都使用相同的基础镜像,这个镜像在所有机器上都只会拉取一遍。

另外,Alpine Linux使用了musl,可能和其他Linux发行版使用的glibc实现会有所不同。在容器化中最可能遇到的是DNS问题,即musl实现的DNS服务不会使用resolv.conf文件中的search和domain两个配置,这对于一些通过DNS来进行服务发现的框架可能会遇到问题。

总结

Alpine Linux,一个只有5M的Docker镜像,它尽可能的简化了镜像的大小,易于分发,有着完善的包管理器和预编译的包。如果你需要一个干净、简洁的容器,开始尝试使用吧!

转载自 infoQ


Linux 命令之basename、dirname

basename命令用于去掉文件名的目录和后缀,dirname命令用于截取目录

path dirname basename
“/usr/lib” “/usr” “lib”
“/usr/” ”/” “usr”
“usr” ”.” “usr”
”/” ”/” ”/”
”.” ”.” ”.”
”..” ”.” ”..”

语法

basename String [ Suffix ]
dirname [ Option ] Name

basename 命令读取 String 参数,删除以 /(斜杠) 结尾的前缀以及任何指定的 Suffix 参数,并将剩余的基本文件名称写至标准输出。dirname则相反。

代码实例

#!/bin/sh  
  
# 跳转到脚本所在目录  
cd $(dirname "$0") || exit 1  
// cd `dirname $0`

man文档

basename

NAME
       basename - strip directory and suffix from filenames

SYNOPSIS
       basename NAME [SUFFIX]
       basename OPTION... NAME...

DESCRIPTION
       Print NAME with any leading directory components removed.  If specified, also remove a trailing SUFFIX.

       Mandatory arguments to long options are mandatory for short options too.

       -a, --multiple
              support multiple arguments and treat each as a NAME

       -s, --suffix=SUFFIX
              remove a trailing SUFFIX; implies -a

       -z, --zero
              end each output line with NUL, not newline

       --help display this help and exit

       --version
              output version information and exit

EXAMPLES
       basename /usr/bin/sort
              -> "sort"

       basename include/stdio.h .h
              -> "stdio"

       basename -s .h include/stdio.h
              -> "stdio"

       basename -a any/str1 any/str2
              -> "str1" followed by "str2"

dirname

NAME
       dirname - strip last component from file name

SYNOPSIS
       dirname [OPTION] NAME...

DESCRIPTION
       Output each NAME with its last non-slash component and trailing slashes removed; if NAME contains no /'s, output '.' (meaning the current directory).

       -z, --zero
              end each output line with NUL, not newline

       --help display this help and exit

       --version
              output version information and exit

EXAMPLES
       dirname /usr/bin/
              -> "/usr"

       dirname dir1/str dir2/str
              -> "dir1" followed by "dir2"

       dirname stdio.h
              -> "."