暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Yzncms [ 御宅男工作室 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2018 http://yzncms.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: 御宅男 <530765310@qq.com>
  10. // +----------------------------------------------------------------------
  11. // +----------------------------------------------------------------------
  12. // | SQL
  13. // +----------------------------------------------------------------------
  14. namespace util;
  15. /**
  16. * 读取Sql文件并返回可执行的sql语句
  17. */
  18. class Sql
  19. {
  20. /**
  21. * 从sql文件获取纯sql语句
  22. *
  23. * @param string $sql_file sql文件路径
  24. * @param bool $string 如果为真,则只返回一条sql语句,默认以数组形式返回
  25. * @param array $replace 替换前缀,如:['my_' => 'me_'],表示将表前缀"my_"替换成"me_"
  26. * 这种前缀替换方法不一定准确,比如正常内容内有跟前缀相同的字符,也会被替换
  27. *
  28. * @return array|false|string
  29. */
  30. public static function getSqlFromFile($sql_file = '', $string = false, $replace = [])
  31. {
  32. if (!file_exists($sql_file)) {
  33. return false;
  34. }
  35. // 读取sql文件内容
  36. $handle = self::read_file($sql_file);
  37. // 分割语句
  38. $handle = self::parseSql($handle, $string, $replace);
  39. return $handle;
  40. }
  41. /**
  42. * 分割sql语句
  43. * @param string $content sql内容
  44. * @param bool $string 如果为真,则只返回一条sql语句,默认以数组形式返回
  45. * @param array $replace 替换前缀,如:['my_' => 'me_'],表示将表前缀my_替换成me_
  46. * @return array|string 除去注释之后的sql语句数组或一条语句
  47. */
  48. public static function parseSql($content = '', $string = false, $replace = [])
  49. {
  50. // 被替换的前缀
  51. $from = '';
  52. // 要替换的前缀
  53. $to = '';
  54. // 替换表前缀
  55. if (!empty($replace)) {
  56. $to = current($replace);
  57. $from = current(array_flip($replace));
  58. }
  59. if ($content != '') {
  60. // 纯sql内容
  61. $pure_sql = [];
  62. // 多行注释标记
  63. $comment = false;
  64. // 按行分割,兼容多个平台
  65. $content = str_replace(["\r\n", "\r"], "\n", $content);
  66. $content = explode("\n", trim($content));
  67. // 循环处理每一行
  68. foreach ($content as $key => $line) {
  69. // 跳过空行
  70. if ($line == '') {
  71. continue;
  72. }
  73. // 跳过以#或者--开头的单行注释
  74. if (preg_match("/^(#|--)/", $line)) {
  75. continue;
  76. }
  77. // 跳过以/**/包裹起来的单行注释
  78. if (preg_match("/^\/\*(.*?)\*\//", $line)) {
  79. continue;
  80. }
  81. // 多行注释开始
  82. if (substr($line, 0, 2) == '/*') {
  83. $comment = true;
  84. continue;
  85. }
  86. // 多行注释结束
  87. if (substr($line, -2) == '*/') {
  88. $comment = false;
  89. continue;
  90. }
  91. // 多行注释没有结束,继续跳过
  92. if ($comment) {
  93. continue;
  94. }
  95. // 替换表前缀
  96. if ($from != '') {
  97. $line = str_replace('`' . $from, '`' . $to, $line);
  98. }
  99. // sql语句
  100. array_push($pure_sql, $line);
  101. }
  102. // 只返回一条语句
  103. if ($string) {
  104. return implode("", $pure_sql);
  105. }
  106. // 以数组形式返回sql语句
  107. $pure_sql = implode("\n", $pure_sql);
  108. $pure_sql = explode(";\n", $pure_sql);
  109. return $pure_sql;
  110. } else {
  111. return $string == true ? '' : [];
  112. }
  113. }
  114. /**
  115. * 读取文件内容
  116. * @param $filename 文件名
  117. * @return string 文件内容
  118. */
  119. public static function read_file($filename)
  120. {
  121. $content = '';
  122. if (function_exists('file_get_contents')) {
  123. @$content = file_get_contents($filename);
  124. } else {
  125. if (@$fp = fopen($filename, 'r')) {
  126. @$content = fread($fp, filesize($filename));
  127. @fclose($fp);
  128. }
  129. }
  130. return $content;
  131. }
  132. }