一直在用 composer,最近想看一下具体的原理是什么,就仔细阅读了一下源码,一下是个人理解。在看该文章前最好了解一下 PSR-4 自动加载规范

引入类自动加载文件

  1. # 加载类自动加载文件
  2. require __DIR__.'/../vendor/autoload.php';
  3. # autoload.php 入口文件
  4. require_once __DIR__ . '/composer/autoload_real.php';
  5. return ComposerAutoloaderInit8ff9bdcc605ff8ad74a329b1634c155c::getLoader();

composer 目录文件

根目录 composer/

  • autoload_namespaces.php 为需要加载的命名空间前缀定义路径
  • autoload_classmap.php 为所有需要自动加载的类定义路径
  • autoload_files.php 定义所有需要加载的配置文件
  • autoload_psr4.php 根据 Psr4 规范定义命名空间前缀和路径
  • autoload_static.php 包含所有需要加载的文件、类,内容包含以上文件
  • autoload_real.php 自动加载配置
  • ClassLoader.php 自动加载类

autoload_real.php 解析

  1. <?php
  2. // autoload_real.php @generated by Composer
  3. class ComposerAutoloaderInit8ff9bdcc605ff8ad74a329b1634c155c
  4. {
  5. private static $loader;
  6. public static function loadClassLoader($class)
  7. {
  8. // 调用自动加载类 ClassLoader.php
  9. if ('Composer\Autoload\ClassLoader' === $class) {
  10. require __DIR__ . '/ClassLoader.php';
  11. }
  12. }
  13. // 实例化 ClassLoader 类,并注册所有需要加载文件的地址
  14. public static function getLoader()
  15. {
  16. if (null !== self::$loader) {
  17. return self::$loader;
  18. }
  19. // 将 loadClassLoader 注册为 __autoload 函数
  20. spl_autoload_register(array('ComposerAutoloaderInit8ff9bdcc605ff8ad74a329b1634c155c', 'loadClassLoader'), true, true);
  21. // 实例化自动加载类
  22. self::$loader = $loader = new \Composer\Autoload\ClassLoader();
  23. // 注销 __autoload 函数
  24. spl_autoload_unregister(array('ComposerAutoloaderInit8ff9bdcc605ff8ad74a329b1634c155c', 'loadClassLoader'));
  25. // 判断 PHP 版本 以及 HHVM_VERSION
  26. $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
  27. if ($useStaticLoader) {
  28. // autoload_static.php 为所有需要加载的文件
  29. require_once __DIR__ . '/autoload_static.php';
  30. // 初始化需要加载的数据,调用通过 autoload_static.php 中定义的值
  31. call_user_func(\Composer\Autoload\ComposerStaticInit8ff9bdcc605ff8ad74a329b1634c155c::getInitializer($loader));
  32. } else {
  33. // 加载的已定义命名空间
  34. $map = require __DIR__ . '/autoload_namespaces.php';
  35. foreach ($map as $namespace => $path) {
  36. $loader->set($namespace, $path);
  37. }
  38. // 加载已定义的命名空间前缀和路径
  39. $map = require __DIR__ . '/autoload_psr4.php';
  40. foreach ($map as $namespace => $path) {
  41. $loader->setPsr4($namespace, $path);
  42. }
  43. // 加载已定义的所有类
  44. $classMap = require __DIR__ . '/autoload_classmap.php';
  45. if ($classMap) {
  46. $loader->addClassMap($classMap);
  47. }
  48. }
  49. // 注册自动加载方法 __atuoload()
  50. $loader->register(true);
  51. if ($useStaticLoader) {
  52. // 加载基础配置文件
  53. $includeFiles = Composer\Autoload\ComposerStaticInit8ff9bdcc605ff8ad74a329b1634c155c::$files;
  54. } else {
  55. $includeFiles = require __DIR__ . '/autoload_files.php';
  56. }
  57. foreach ($includeFiles as $fileIdentifier => $file) {
  58. composerRequire8ff9bdcc605ff8ad74a329b1634c155c($fileIdentifier, $file);
  59. }
  60. return $loader;
  61. }
  62. }
  63. function composerRequire8ff9bdcc605ff8ad74a329b1634c155c($fileIdentifier, $file)
  64. {
  65. if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
  66. // 调用配置文件
  67. require $file;
  68. $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
  69. }
  70. }

autoload_static.php 解析

  1. <?php
  2. // autoload_static.php @generated by Composer
  3. namespace Composer\Autoload;
  4. class ComposerStaticInit8ff9bdcc605ff8ad74a329b1634c155c
  5. {
  6. // 基础文件
  7. public static $files = array (
  8. '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/custom/sub-custom/custom.php',
  9. );
  10. // 命名空间前缀及长度
  11. public static $prefixLengthsPsr4 = array (
  12. 'p' =>
  13. array (
  14. 'custom\\sub-custom\\' => 18,
  15. ),
  16. );
  17. // 命名空间前缀及路径
  18. public static $prefixDirsPsr4 = array (
  19. 'sustom\\sub-custom\\' =>
  20. array (
  21. 0 => __DIR__ . '/..' . '/custom/sub-custom/custom',
  22. ),
  23. );
  24. // 命名空间前缀及路径
  25. public static $prefixesPsr0 = array (
  26. 'C' =>
  27. array (
  28. 'Custom\\' =>
  29. array (
  30. 0 => __DIR__ . '/..' . '/custom/sub-custom/custom',
  31. ),
  32. ),
  33. // 所有需要自动加载的类
  34. public static $classMap = array (
  35. 'Custom\\CustomController' => __DIR__ . '/../..' . 'Custom/CustomController.php',
  36. )
  37. public static function getInitializer(ClassLoader $loader)
  38. {
  39. return \Closure::bind(function () use ($loader) {
  40. $loader->prefixLengthsPsr4 = ComposerStaticInit8ff9bdcc605ff8ad74a329b1634c155c::$prefixLengthsPsr4;
  41. $loader->prefixDirsPsr4 = ComposerStaticInit8ff9bdcc605ff8ad74a329b1634c155c::$prefixDirsPsr4;
  42. $loader->prefixesPsr0 = ComposerStaticInit8ff9bdcc605ff8ad74a329b1634c155c::$prefixesPsr0;
  43. // 以上为 PHP 自动加载规范
  44. // 以下为需要加载的类
  45. $loader->classMap = ComposerStaticInit8ff9bdcc605ff8ad74a329b1634c155c::$classMap;
  46. }, null, ClassLoader::class);
  47. }

ClassLoader.php 解析

  1. <?php
  2. /*
  3. * This file is part of Composer.
  4. *
  5. * (c) Nils Adermann <naderman@naderman.de>
  6. * Jordi Boggiano <j.boggiano@seld.be>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Composer\Autoload;
  12. /**
  13. * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
  14. *
  15. * $loader = new \Composer\Autoload\ClassLoader();
  16. *
  17. * // register classes with namespaces
  18. * $loader->add('Symfony\Component', __DIR__.'/component');
  19. * $loader->add('Symfony', __DIR__.'/framework');
  20. *
  21. * // activate the autoloader
  22. * $loader->register();
  23. *
  24. * // to enable searching the include path (eg. for PEAR packages)
  25. * $loader->setUseIncludePath(true);
  26. *
  27. * In this example, if you try to use a class in the Symfony\Component
  28. * namespace or one of its children (Symfony\Component\Console for instance),
  29. * the autoloader will first look for the class under the component/
  30. * directory, and it will then fallback to the framework/ directory if not
  31. * found before giving up.
  32. *
  33. * This class is loosely based on the Symfony UniversalClassLoader.
  34. *
  35. * @author Fabien Potencier <fabien@symfony.com>
  36. * @author Jordi Boggiano <j.boggiano@seld.be>
  37. * @see http://www.php-fig.org/psr/psr-0/
  38. * @see http://www.php-fig.org/psr/psr-4/
  39. */
  40. class ClassLoader
  41. {
  42. // PSR-4
  43. private $prefixLengthsPsr4 = array();
  44. private $prefixDirsPsr4 = array();
  45. private $fallbackDirsPsr4 = array();
  46. // PSR-0
  47. private $prefixesPsr0 = array();
  48. private $fallbackDirsPsr0 = array();
  49. private $useIncludePath = false;
  50. private $classMap = array();
  51. private $classMapAuthoritative = false;
  52. private $missingClasses = array();
  53. private $apcuPrefix;
  54. public function getPrefixes()
  55. {
  56. if (!empty($this->prefixesPsr0)) {
  57. return call_user_func_array('array_merge', $this->prefixesPsr0);
  58. }
  59. return array();
  60. }
  61. public function getPrefixesPsr4()
  62. {
  63. return $this->prefixDirsPsr4;
  64. }
  65. public function getFallbackDirs()
  66. {
  67. return $this->fallbackDirsPsr0;
  68. }
  69. public function getFallbackDirsPsr4()
  70. {
  71. return $this->fallbackDirsPsr4;
  72. }
  73. public function getClassMap()
  74. {
  75. return $this->classMap;
  76. }
  77. /**
  78. * @param array $classMap Class to filename map
  79. */
  80. public function addClassMap(array $classMap)
  81. {
  82. if ($this->classMap) {
  83. $this->classMap = array_merge($this->classMap, $classMap);
  84. } else {
  85. $this->classMap = $classMap;
  86. }
  87. }
  88. /**
  89. * Registers a set of PSR-0 directories for a given prefix, either
  90. * appending or prepending to the ones previously set for this prefix.
  91. *
  92. * @param string $prefix The prefix
  93. * @param array|string $paths The PSR-0 root directories
  94. * @param bool $prepend Whether to prepend the directories
  95. */
  96. public function add($prefix, $paths, $prepend = false)
  97. {
  98. if (!$prefix) {
  99. if ($prepend) {
  100. $this->fallbackDirsPsr0 = array_merge(
  101. (array) $paths,
  102. $this->fallbackDirsPsr0
  103. );
  104. } else {
  105. $this->fallbackDirsPsr0 = array_merge(
  106. $this->fallbackDirsPsr0,
  107. (array) $paths
  108. );
  109. }
  110. return;
  111. }
  112. $first = $prefix[0];
  113. if (!isset($this->prefixesPsr0[$first][$prefix])) {
  114. $this->prefixesPsr0[$first][$prefix] = (array) $paths;
  115. return;
  116. }
  117. if ($prepend) {
  118. $this->prefixesPsr0[$first][$prefix] = array_merge(
  119. (array) $paths,
  120. $this->prefixesPsr0[$first][$prefix]
  121. );
  122. } else {
  123. $this->prefixesPsr0[$first][$prefix] = array_merge(
  124. $this->prefixesPsr0[$first][$prefix],
  125. (array) $paths
  126. );
  127. }
  128. }
  129. /**
  130. * Registers a set of PSR-4 directories for a given namespace, either
  131. * appending or prepending to the ones previously set for this namespace.
  132. *
  133. * @param string $prefix The prefix/namespace, with trailing '\\'
  134. * @param array|string $paths The PSR-4 base directories
  135. * @param bool $prepend Whether to prepend the directories
  136. *
  137. * @throws \InvalidArgumentException
  138. */
  139. public function addPsr4($prefix, $paths, $prepend = false)
  140. {
  141. if (!$prefix) {
  142. // Register directories for the root namespace.
  143. if ($prepend) {
  144. $this->fallbackDirsPsr4 = array_merge(
  145. (array) $paths,
  146. $this->fallbackDirsPsr4
  147. );
  148. } else {
  149. $this->fallbackDirsPsr4 = array_merge(
  150. $this->fallbackDirsPsr4,
  151. (array) $paths
  152. );
  153. }
  154. } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
  155. // Register directories for a new namespace.
  156. $length = strlen($prefix);
  157. if ('\\' !== $prefix[$length - 1]) {
  158. throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
  159. }
  160. $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
  161. $this->prefixDirsPsr4[$prefix] = (array) $paths;
  162. } elseif ($prepend) {
  163. // Prepend directories for an already registered namespace.
  164. $this->prefixDirsPsr4[$prefix] = array_merge(
  165. (array) $paths,
  166. $this->prefixDirsPsr4[$prefix]
  167. );
  168. } else {
  169. // Append directories for an already registered namespace.
  170. $this->prefixDirsPsr4[$prefix] = array_merge(
  171. $this->prefixDirsPsr4[$prefix],
  172. (array) $paths
  173. );
  174. }
  175. }
  176. /**
  177. * Registers a set of PSR-0 directories for a given prefix,
  178. * replacing any others previously set for this prefix.
  179. *
  180. * @param string $prefix The prefix
  181. * @param array|string $paths The PSR-0 base directories
  182. */
  183. public function set($prefix, $paths)
  184. {
  185. if (!$prefix) {
  186. $this->fallbackDirsPsr0 = (array) $paths;
  187. } else {
  188. $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
  189. }
  190. }
  191. /**
  192. * Registers a set of PSR-4 directories for a given namespace,
  193. * replacing any others previously set for this namespace.
  194. *
  195. * @param string $prefix The prefix/namespace, with trailing '\\'
  196. * @param array|string $paths The PSR-4 base directories
  197. *
  198. * @throws \InvalidArgumentException
  199. */
  200. public function setPsr4($prefix, $paths)
  201. {
  202. if (!$prefix) {
  203. $this->fallbackDirsPsr4 = (array) $paths;
  204. } else {
  205. $length = strlen($prefix);
  206. if ('\\' !== $prefix[$length - 1]) {
  207. throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
  208. }
  209. $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
  210. $this->prefixDirsPsr4[$prefix] = (array) $paths;
  211. }
  212. }
  213. /**
  214. * Turns on searching the include path for class files.
  215. *
  216. * @param bool $useIncludePath
  217. */
  218. public function setUseIncludePath($useIncludePath)
  219. {
  220. $this->useIncludePath = $useIncludePath;
  221. }
  222. /**
  223. * Can be used to check if the autoloader uses the include path to check
  224. * for classes.
  225. *
  226. * @return bool
  227. */
  228. public function getUseIncludePath()
  229. {
  230. return $this->useIncludePath;
  231. }
  232. /**
  233. * Turns off searching the prefix and fallback directories for classes
  234. * that have not been registered with the class map.
  235. *
  236. * @param bool $classMapAuthoritative
  237. */
  238. public function setClassMapAuthoritative($classMapAuthoritative)
  239. {
  240. $this->classMapAuthoritative = $classMapAuthoritative;
  241. }
  242. /**
  243. * Should class lookup fail if not found in the current class map?
  244. *
  245. * @return bool
  246. */
  247. public function isClassMapAuthoritative()
  248. {
  249. return $this->classMapAuthoritative;
  250. }
  251. /**
  252. * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
  253. *
  254. * @param string|null $apcuPrefix
  255. */
  256. public function setApcuPrefix($apcuPrefix)
  257. {
  258. $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
  259. }
  260. /**
  261. * The APCu prefix in use, or null if APCu caching is not enabled.
  262. *
  263. * @return string|null
  264. */
  265. public function getApcuPrefix()
  266. {
  267. return $this->apcuPrefix;
  268. }
  269. /**
  270. * Registers this instance as an autoloader.
  271. *
  272. * @param bool $prepend Whether to prepend the autoloader or not
  273. */
  274. public function register($prepend = false)
  275. {
  276. spl_autoload_register(array($this, 'loadClass'), true, $prepend);
  277. }
  278. /**
  279. * Unregisters this instance as an autoloader.
  280. */
  281. public function unregister()
  282. {
  283. spl_autoload_unregister(array($this, 'loadClass'));
  284. }
  285. /**
  286. * Loads the given class or interface.
  287. *
  288. * @param string $class The name of the class
  289. * @return bool|null True if loaded, null otherwise
  290. */
  291. public function loadClass($class)
  292. {
  293. if ($file = $this->findFile($class)) {
  294. includeFile($file);
  295. return true;
  296. }
  297. }
  298. /**
  299. * Finds the path to the file where the class is defined.
  300. *
  301. * @param string $class The name of the class
  302. *
  303. * @return string|false The path if found, false otherwise
  304. */
  305. public function findFile($class)
  306. {
  307. // class map lookup
  308. // 如果存在直接返回
  309. if (isset($this->classMap[$class])) {
  310. return $this->classMap[$class];
  311. }
  312. if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
  313. return false;
  314. }
  315. if (null !== $this->apcuPrefix) {
  316. $file = apcu_fetch($this->apcuPrefix.$class, $hit);
  317. if ($hit) {
  318. return $file;
  319. }
  320. }
  321. // 没有在 classMap中找到,重新查找
  322. $file = $this->findFileWithExtension($class, '.php');
  323. // Search for Hack files if we are running on HHVM
  324. if (false === $file && defined('HHVM_VERSION')) {
  325. $file = $this->findFileWithExtension($class, '.hh');
  326. }
  327. if (null !== $this->apcuPrefix) {
  328. apcu_add($this->apcuPrefix.$class, $file);
  329. }
  330. if (false === $file) {
  331. // Remember that this class does not exist.
  332. $this->missingClasses[$class] = true;
  333. }
  334. return $file;
  335. }
  336. private function findFileWithExtension($class, $ext)
  337. {
  338. // PSR-4 lookup
  339. $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
  340. $first = $class[0];
  341. if (isset($this->prefixLengthsPsr4[$first])) {
  342. $subPath = $class;
  343. while (false !== $lastPos = strrpos($subPath, '\\')) {
  344. $subPath = substr($subPath, 0, $lastPos);
  345. $search = $subPath.'\\';
  346. if (isset($this->prefixDirsPsr4[$search])) {
  347. foreach ($this->prefixDirsPsr4[$search] as $dir) {
  348. $length = $this->prefixLengthsPsr4[$first][$search];
  349. if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
  350. return $file;
  351. }
  352. }
  353. }
  354. }
  355. }
  356. // PSR-4 fallback dirs
  357. foreach ($this->fallbackDirsPsr4 as $dir) {
  358. if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
  359. return $file;
  360. }
  361. }
  362. // PSR-0 lookup
  363. if (false !== $pos = strrpos($class, '\\')) {
  364. // namespaced class name
  365. $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
  366. . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
  367. } else {
  368. // PEAR-like class name
  369. $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
  370. }
  371. if (isset($this->prefixesPsr0[$first])) {
  372. foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
  373. if (0 === strpos($class, $prefix)) {
  374. foreach ($dirs as $dir) {
  375. if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
  376. return $file;
  377. }
  378. }
  379. }
  380. }
  381. }
  382. // PSR-0 fallback dirs
  383. foreach ($this->fallbackDirsPsr0 as $dir) {
  384. if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
  385. return $file;
  386. }
  387. }
  388. // PSR-0 include paths.
  389. if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
  390. return $file;
  391. }
  392. return false;
  393. }
  394. }
  395. /**
  396. * Scope isolated include.
  397. *
  398. * Prevents access to $this/self from included files.
  399. */
  400. function includeFile($file)
  401. {
  402. include $file;
  403. }

composer 自动加载源码解析的更多相关文章

  1. eclipse中自动加载源码的方法

    1.选中项目右键properties--java build path--Libraries--Add External class Folder 找到项目将项目添加进去 2.然后就是这样 3.OK

  2. PHP自动加载功能原理解析

    前言 这篇文章是对PHP自动加载功能的一个总结,内容涉及PHP的自动加载功能.PHP的命名空间.PHP的PSR0与PSR4标准等内容. 一.PHP自动加载功能 PHP自动加载功能的由来 在PHP开发过 ...

  3. lumen之composer自动加载

    composer作为PHP的包管理工具,让PHP可以使用命名空间, 载入对应的类文件,不用理会文件引入的路劲问题,代码可读性也大大提高 composer 自动加载 composer 自动加载的规则 v ...

  4. Laravel 学习笔记之 Composer 自动加载

    说明:本文主要以Laravel的容器类Container为例做简单说明Composer的自动加载机制. Composer的自动加载机制 1.初始化一个composer项目 在一个空目录下compose ...

  5. SpringBoot自动配置的源码解析

    首先,写源码分析真的很花时间,所以希望大家转的时候也请注明一下,Thanks♪(・ω・)ノ SpringBoot最大的好处就是对于很多框架都默认的配置,让我们开发的时候不必为了大一堆的配置文件头疼,关 ...

  6. composer 自动加载(php-amqplib)

    最近要使用RabbitMQ 做消息队列,也是刚接触到.因为用的的TP框架,comoser又下载不下来,所以只能手动下载拓展包,做手动加载,在php-amqplib是我手动下载下来的拓展包,创建一个co ...

  7. composer 自动加载一 通过file加载

    github地址 https://github.com/brady-wang/composer composer init 可以生成一个composer.json文件 { "name&quo ...

  8. Composer 自动加载(autoload)机制

    自动加载的类型 总体来说 composer 提供了几种自动加载类型 classmap psr-0 psr-4 files 这几种自动加载都会用到,理论上来说,项目代码用 psr-4 自动加载, hel ...

  9. composer自动加载一个文件后必须执行命令composer dump-autoload

    "autoload": { "classmap": [ "database" ], "psr-4": { "A ...

随机推荐

  1. @Modifying 注解完成修改操作

    以上我们做的都是查询,那要如何实现 修改.删除和添加呢? 可以通过以下两种方式: (1)通过实现 CrudRepository 接口来完成(以后介绍): (2)通过 @Modifying 注解完成修改 ...

  2. LeetCode 148 Sort List 链表上的归并排序和快速排序

    Sort a linked list in O(n log n) time using constant space complexity. 单链表排序----快排 & 归并排序 (1)归并排 ...

  3. 二维hash

    题目描述 给出一个n * m的矩阵.让你从中发现一个最大的正方形.使得这样子的正方形在矩阵中出现了至少两次.输出最大正方形的边长. 输入描述: 第一行两个整数n, m代表矩阵的长和宽: 接下来n行,每 ...

  4. Java面向对象_抽象类应用——模板方法模式

    概念:定义一个操作中的算法的骨架,而将一些可变部分的实现延迟到子类中.模板方法模式使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定的步骤. 去个例子分析一下这个概念: public cla ...

  5. Unity3D游戏高性能战争迷雾系统实现

    一 效果图 先上效果图吧,这是为了吸引到你们的ヽ(。◕‿◕。)ノ゚ 战争迷雾效果演示图 战争迷雾调试界面演示图 由于是gif录制,为了压缩图片,帧率有点低,实际运行时,参数调整好是不会像这样一卡一顿的 ...

  6. phpize使用方法

    phpize是用来扩展php扩展模块的,通过phpize可以建立php的外挂模块,下面介绍一个它的使用方法,需要的朋友可以参考下 安装(fastcgi模式)的时候,常常有这样一句命令: 代码如下: / ...

  7. 3年,阅读量100万+, Github Star 15000+

    这两天突然发现,三年前在博客园写的一篇文章阅读量超过百万了,对,还是技术文章.这个让我蛮惊讶的,当时刚开始写这篇文章的时候,一周的阅读量也才两三千,随着时间慢慢的过去,在搜索引擎的加持下竟然超过了百万 ...

  8. 操作文件方法简单总结(File,Directory,StreamReader,StreamWrite )(转载)

    本文转自http://www.cnblogs.com/zery/p/3315889.html 对于文件夹,文档的操作一直处于一知半解状态,有时间闲下来了,好好练习了一把,对文档,文件的操作有了一个基本 ...

  9. ngnix反向代理

    https://blog.csdn.net/sherry_chan/article/details/79055211

  10. 【转】【C++】【MFC】各种数据类型大小

    *原文地址:http://blog.csdn.net/xuexiacm/article/details/8122267 /*运行结果分析: 以上结果已经很明白了,一下补充说明几点: 概念.整型:表示整 ...