splfileobject.inc 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. <?php
  2. /** @file splfileobject.inc
  3. * @ingroup SPL
  4. * @brief class FileObject
  5. * @author Marcus Boerger
  6. * @date 2003 - 2009
  7. *
  8. * SPL - Standard PHP Library
  9. */
  10. /** @ingroup SPL
  11. * @brief Object representation for any stream
  12. * @author Marcus Boerger
  13. * @version 1.1
  14. * @since PHP 5.1
  15. */
  16. class SplFileObject extends SplFileInfo implements RecursiveIterator, SeekableIterator
  17. {
  18. /** Flag: wheter to suppress new lines */
  19. const DROP_NEW_LINE = 0x00000001;
  20. private $fp;
  21. private $fname;
  22. private $line = NULL;
  23. private $lnum = 0;
  24. private $max_len = 0;
  25. private $flags = 0;
  26. private $delimiter= ',';
  27. private $enclosure= '"';
  28. /**
  29. * Constructs a new file object
  30. *
  31. * @param $file_name The name of the stream to open
  32. * @param $open_mode The file open mode
  33. * @param $use_include_path Whether to search in include paths
  34. * @param $context A stream context
  35. * @throw RuntimeException If file cannot be opened (e.g. insufficient
  36. * access rights).
  37. */
  38. function __construct($file_name, $open_mode = 'r', $use_include_path = false, $context = NULL)
  39. {
  40. $this->fp = fopen($file_name, $open_mode, $use_include_path, $context);
  41. if (!$this->fp)
  42. {
  43. throw new RuntimeException("Cannot open file $file_name");
  44. }
  45. $this->fname = $file_name;
  46. }
  47. /**
  48. * @return whether the end of the stream is reached
  49. */
  50. function eof()
  51. {
  52. return eof($this->fp);
  53. }
  54. /** increase current line number
  55. * @return next line from stream
  56. */
  57. function fgets()
  58. {
  59. $this->freeLine();
  60. $this->lnum++;
  61. $buf = fgets($this->fp, $this->max_len);
  62. return $buf;
  63. }
  64. /**
  65. * @param delimiter character used as field separator
  66. * @param enclosure end of
  67. * @return array containing read data
  68. */
  69. function fgetcsv($delimiter = NULL, $enclosure = NULL)
  70. {
  71. $this->freeLine();
  72. $this->lnum++;
  73. switch(fun_num_args())
  74. {
  75. case 0:
  76. $delimiter = $this->delimiter;
  77. case 1:
  78. $enclosure = $this->enclosure;
  79. default:
  80. case 2:
  81. break;
  82. }
  83. return fgetcsv($this->fp, $this->max_len, $delimiter, $enclosure);
  84. }
  85. /**
  86. * Set the delimiter and enclosure character used in fgetcsv
  87. *
  88. * @param delimiter new delimiter, defaults to ','
  89. * @param enclosure new enclosure, defaults to '"'
  90. */
  91. function setCsvControl($delimiter = ';', $enclosure = '"')
  92. {
  93. $this->delimiter = $delimiter;
  94. $this->enclosure = $enclosure;
  95. }
  96. /**
  97. * @return array(delimiter, enclosure) as used in fgetcsv
  98. */
  99. function getCsvControl($delimiter = ',', $enclosure = '"')
  100. {
  101. return array($this->delimiter, $this->enclosure);
  102. }
  103. /**
  104. * @param operation lock operation (LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB)
  105. * @retval $wouldblock whether the operation would block
  106. */
  107. function flock($operation, &$wouldblock)
  108. {
  109. return flock($this->fp, $operation, $wouldblock);
  110. }
  111. /**
  112. * Flush current data
  113. * @return success or failure
  114. */
  115. function fflush()
  116. {
  117. return fflush($this->fp);
  118. }
  119. /**
  120. * @return current file position
  121. */
  122. function ftell()
  123. {
  124. return ftell($this->fp);
  125. }
  126. /**
  127. * @param pos new file position
  128. * @param whence seek method (SEEK_SET, SEEK_CUR, SEEK_END)
  129. * @return Upon success, returns 0; otherwise, returns -1. Note that
  130. * seeking past EOF is not considered an error.
  131. */
  132. function fseek($pos, $whence = SEEK_SET)
  133. {
  134. return fseek($this->fp, $pos, $whence);
  135. }
  136. /**
  137. * @return next char from file
  138. * @note a new line character does not increase $this->lnum
  139. */
  140. function fgetc()
  141. {
  142. $this->freeLine();
  143. $c = fgetc($this->fp);
  144. if ($c == '\n') {
  145. $this->lnum++;
  146. }
  147. }
  148. /** Read and return remaining part of stream
  149. * @return size of remaining part passed through
  150. */
  151. function fpassthru()
  152. {
  153. return fpassthru($this->fp);
  154. }
  155. /** Get a line from the file and strip HTML tags
  156. * @param $allowable_tags tags to keep in the string
  157. */
  158. function fgetss($allowable_tags = NULL)
  159. {
  160. return fgetss($this->fp, $allowable_tags);
  161. }
  162. /** Scan the next line
  163. * @param $format string specifying format to parse
  164. */
  165. function fscanf($format /* , ... */)
  166. {
  167. $this->freeLine();
  168. $this->lnum++;
  169. return fscanf($this->fp, $format /* , ... */);
  170. }
  171. /**
  172. * @param $str to write
  173. * @param $length maximum line length to write
  174. */
  175. function fwrite($str, $length = NULL)
  176. {
  177. return fwrite($this->fp, $length);
  178. }
  179. /**
  180. * @return array of file stat information
  181. */
  182. function fstat()
  183. {
  184. return fstat($this->fp);
  185. }
  186. /**
  187. * @param $size new size to truncate file to
  188. */
  189. function ftruncate($size)
  190. {
  191. return ftruncate($this->fp, $size);
  192. }
  193. /**
  194. * @param $flags new flag set
  195. */
  196. function setFlags($flags)
  197. {
  198. $this->flags = $flags;
  199. }
  200. /**
  201. * @return current set of flags
  202. */
  203. function getFlags()
  204. {
  205. return $this->flags;
  206. }
  207. /**
  208. * @param $max_len set the maximum line length read
  209. */
  210. function setMaxLineLen($max_len)
  211. {
  212. $this->max_len = $max_len;
  213. }
  214. /**
  215. * @return current setting for max line
  216. */
  217. function getMaxLineLen()
  218. {
  219. return $this->max_len;
  220. }
  221. /**
  222. * @return false
  223. */
  224. function hasChildren()
  225. {
  226. return false;
  227. }
  228. /**
  229. * @return false
  230. */
  231. function getChildren()
  232. {
  233. return NULL;
  234. }
  235. /**
  236. * Invalidate current line buffer and set line number to 0.
  237. */
  238. function rewind()
  239. {
  240. $this->freeLine();
  241. $this->lnum = 0;
  242. }
  243. /**
  244. * @return whether more data can be read
  245. */
  246. function valid()
  247. {
  248. return !$this->eof();
  249. }
  250. /**
  251. * @note Fill current line buffer if not done yet.
  252. * @return line buffer
  253. */
  254. function current()
  255. {
  256. if (is_null($this->line))
  257. {
  258. $this->line = getCurrentLine();
  259. }
  260. return $this->line;
  261. }
  262. /**
  263. * @return line number
  264. * @note fgetc() will increase the line number when reaing a new line char.
  265. * This has the effect key() called on a read a new line will already
  266. * return the increased line number.
  267. * @note Line counting works as long as you only read the file and do not
  268. * use fseek().
  269. */
  270. function key()
  271. {
  272. return $this->lnum;
  273. }
  274. /** Invalidate current line buffer.
  275. */
  276. function next()
  277. {
  278. $this->freeLine();
  279. }
  280. /**
  281. * @return next line read from file and increase the line counter
  282. */
  283. private function readLine()
  284. {
  285. if ($this->eof())
  286. {
  287. $this->freeLine();
  288. throw new RuntimeException("Cannot read from file " . $this->fname);
  289. }
  290. if ($this->line) {
  291. $this->lnum++;
  292. }
  293. $this->freeLine();
  294. $this->line = fgets($this->fp, $this->max_len);
  295. return $this->line;
  296. }
  297. /**
  298. * Free the current line buffer and increment the line counter
  299. */
  300. private function freeLine()
  301. {
  302. if ($this->line) {
  303. $this->line = NULL;
  304. }
  305. }
  306. /*
  307. * @note If you DO overload this function key() and current() will increment
  308. * $this->lnum automatically. If not then function reaLine() will do
  309. * that for you.
  310. */
  311. function getCurrentLine()
  312. {
  313. $this->freeLine();
  314. if ($this->eof())
  315. {
  316. throw new RuntimeException("Cannot read from file " . $this->fname);
  317. }
  318. $this->readLine();
  319. }
  320. /**
  321. * @return current line
  322. */
  323. function __toString()
  324. {
  325. return current();
  326. }
  327. /**
  328. * @param $line_pos Seek to this line
  329. */
  330. function seek($line_pos)
  331. {
  332. $this->rewind();
  333. while($this->lnum < $line_pos && !$this->eof())
  334. {
  335. $this->getCurrentLine();
  336. }
  337. }
  338. }
  339. ?>