php-tail 추가

This commit is contained in:
2018-04-01 18:44:45 +09:00
parent 74390602d8
commit 5860a14dae
40 changed files with 1928 additions and 2 deletions
+2 -1
View File
@@ -14,7 +14,8 @@
"leafo/scssphp": "^0.7.5",
"monolog/monolog": "^1.23",
"firephp/firephp-core": "^0.4.0",
"vlucas/valitron": "^1.4"
"vlucas/valitron": "^1.4",
"php-extended/php-tail": "^2.1"
},
"autoload": {
"psr-4": {
Generated
+85 -1
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "4659ec09c50a2ccd1b53194b3f53890a",
"content-hash": "4b18f5660106f71d2aba7f1dcee07033",
"packages": [
{
"name": "brandonwamboldt/utilphp",
@@ -454,6 +454,90 @@
],
"time": "2017-06-19T01:22:40+00:00"
},
{
"name": "php-extended/php-system",
"version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/php-extended/php-system.git",
"reference": "66727d5dc0a665916bd7e08bcfb9820e7be1d20c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-extended/php-system/zipball/66727d5dc0a665916bd7e08bcfb9820e7be1d20c",
"reference": "66727d5dc0a665916bd7e08bcfb9820e7be1d20c",
"shasum": ""
},
"type": "library",
"autoload": {
"psr-4": {
"PhpExtended\\System\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Anastaszor",
"role": "developer"
}
],
"description": "A generic way to find informations about the running system",
"homepage": "https://github.com/php-extended/php-system",
"keywords": [
"operating system",
"os",
"php",
"system"
],
"time": "2017-01-14T11:56:24+00:00"
},
{
"name": "php-extended/php-tail",
"version": "2.1.1",
"source": {
"type": "git",
"url": "https://github.com/php-extended/php-tail.git",
"reference": "eabf7bee64f8c30fe9b9e1176562fdb903c54ae7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-extended/php-tail/zipball/eabf7bee64f8c30fe9b9e1176562fdb903c54ae7",
"reference": "eabf7bee64f8c30fe9b9e1176562fdb903c54ae7",
"shasum": ""
},
"require": {
"php-extended/php-system": "^1.2"
},
"type": "library",
"autoload": {
"psr-4": {
"PhpExtended\\Tail\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Anastaszor",
"role": "developer"
}
],
"description": "A smart way to tail files depending of the environment",
"homepage": "https://github.com/php-extended/php-tail",
"keywords": [
"cheat",
"mighty",
"naive",
"php",
"tail"
],
"time": "2017-07-25T13:52:42+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
+2
View File
@@ -10,6 +10,8 @@ return array(
'kakao\\' => array($baseDir . '/d_setting', $baseDir . '/src/kakao'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
'PhpExtended\\Tail\\' => array($vendorDir . '/php-extended/php-tail/src'),
'PhpExtended\\System\\' => array($vendorDir . '/php-extended/php-system/src'),
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
'League\\Plates\\' => array($vendorDir . '/league/plates/src'),
'Leafo\\ScssPhp\\' => array($vendorDir . '/leafo/scssphp/src'),
+10
View File
@@ -25,6 +25,8 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
array (
'Psr\\Log\\' => 8,
'Psr\\Http\\Message\\' => 17,
'PhpExtended\\Tail\\' => 17,
'PhpExtended\\System\\' => 19,
),
'M' =>
array (
@@ -62,6 +64,14 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
array (
0 => __DIR__ . '/..' . '/psr/http-message/src',
),
'PhpExtended\\Tail\\' =>
array (
0 => __DIR__ . '/..' . '/php-extended/php-tail/src',
),
'PhpExtended\\System\\' =>
array (
0 => __DIR__ . '/..' . '/php-extended/php-system/src',
),
'Monolog\\' =>
array (
0 => __DIR__ . '/..' . '/monolog/monolog/src/Monolog',
+88
View File
@@ -463,6 +463,94 @@
"psr-3"
]
},
{
"name": "php-extended/php-system",
"version": "1.3.0",
"version_normalized": "1.3.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-extended/php-system.git",
"reference": "66727d5dc0a665916bd7e08bcfb9820e7be1d20c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-extended/php-system/zipball/66727d5dc0a665916bd7e08bcfb9820e7be1d20c",
"reference": "66727d5dc0a665916bd7e08bcfb9820e7be1d20c",
"shasum": ""
},
"time": "2017-01-14T11:56:24+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"PhpExtended\\System\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Anastaszor",
"role": "developer"
}
],
"description": "A generic way to find informations about the running system",
"homepage": "https://github.com/php-extended/php-system",
"keywords": [
"operating system",
"os",
"php",
"system"
]
},
{
"name": "php-extended/php-tail",
"version": "2.1.1",
"version_normalized": "2.1.1.0",
"source": {
"type": "git",
"url": "https://github.com/php-extended/php-tail.git",
"reference": "eabf7bee64f8c30fe9b9e1176562fdb903c54ae7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-extended/php-tail/zipball/eabf7bee64f8c30fe9b9e1176562fdb903c54ae7",
"reference": "eabf7bee64f8c30fe9b9e1176562fdb903c54ae7",
"shasum": ""
},
"require": {
"php-extended/php-system": "^1.2"
},
"time": "2017-07-25T13:52:42+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"PhpExtended\\Tail\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Anastaszor",
"role": "developer"
}
],
"description": "A smart way to tail files depending of the environment",
"homepage": "https://github.com/php-extended/php-tail",
"keywords": [
"cheat",
"mighty",
"naive",
"php",
"tail"
]
},
{
"name": "psr/http-message",
"version": "1.0.1",
+10
View File
@@ -0,0 +1,10 @@
composer.phar
/vendor/
# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
# composer.lock
.settings/
.buildpath
.project
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+38
View File
@@ -0,0 +1,38 @@
# php-system
A generic way to find informations about your system
## Installation
The installation of this library is made via composer.
Download `composer.phar` from [their website](https://getcomposer.org/download/).
Then add to your composer.json :
```json
"require": {
...
"php-extended/php-system": "^1.0",
...
}
```
Then run `php composer.phar update` to install this library.
The autoloading of all classes of this library is made through composer's autoloader.
## Basic Usage
You can get the singleton php-system object by doing the following:
```php
use PhpExtended\System\OperatingSystem;
$system = OperatingSystem::get();
```
This system object have lots of useful properties. An instance of `UnknownOs` is returned in case this is not implemented.
The `get` method never throws any exception.
## License
MIT (See [license file](LICENSE)).
+27
View File
@@ -0,0 +1,27 @@
{
"name" : "php-extended/php-system",
"description" : "A generic way to find informations about the running system",
"type" : "library",
"homepage" : "https://github.com/php-extended/php-system",
"license" : "MIT",
"authors" : [{
"name" : "Anastaszor",
"role" : "Developer"
}
],
"support" : {
"issues" : "https://github.com/php-extended/php-system/issues",
"source" : "https://github.com/php-extended/php-system"
},
"autoload" : {
"psr-4" : {
"PhpExtended\\System\\" : "src/"
}
},
"keywords" : [
"php",
"system",
"os",
"operating system"
]
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* Cygwin class file.
*
* This class represents an operating system of the Cygwin family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/Cygwin
*/
class Cygwin extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return true;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* Darwin class file.
*
* This class represents an operating system of the Darwin family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/Darwin_(operating_system)
*/
class Darwin extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return true;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* EComStation class file.
*
* This class represents an operating system of the eComStation family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/EComStation
*/
class EComStation extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return false;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* FreeBsd class file.
*
* This class represents an operating system of the FreeBSD family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/FreeBSD
*/
class FreeBsd extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return true;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* HpUx class file.
*
* This class represents an operating system of the HP-UX family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/HP-UX
*/
class HpUx extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return true;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* Irix64 class file.
*
* This class represents an operating system of the IRIX family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/IRIX
*/
class Irix64 extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return true;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace PhpExtended\System;
/**
* Linux class file.
*
* This class is a metaclass that represents all operating systems that
* comply with the linux family and that are not treated as a separate family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/Linux
*/
class Linux extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return true;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* NetBsd class file.
*
* This class represents an operating system of the NetBSD family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/NetBSD
*/
class NetBsd extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return true;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* OpenBsd class file.
*
* This class represents an operating system of the OpenBSD family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/OpenBSD
*/
class OpenBsd extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return true;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+95
View File
@@ -0,0 +1,95 @@
<?php
namespace PhpExtended\System;
/**
* OperatingSystem abstract class file.
*
* Represents the current running operating system. This class is the interface
* for all the lower classes in the hierarchy.
*
* @author Anastaszor
*/
abstract class OperatingSystem
{
/**
* The current running operating system singleton instance.
*
* @var OperatingSystem
*/
private static $_current = null;
/**
* Gets the current running operating system singleton instance.
*
* @return OperatingSystem
*/
public static function get()
{
if(self::$_current === null)
self::$_current = self::factory();
return self::$_current;
}
/**
* Builds the operating system object from php's core parameters.
*
* @return OperatingSystem
*/
private static function factory()
{
switch(PHP_OS)
{
case 'CYGWIN_NT-5.1':
return new Cygwin();
case 'Darwin':
return new Darwin();
case 'FreeBSD':
return new FreeBsd();
case 'HP-UX':
return new HpUx();
case 'IRIX64':
return new Irix64();
case 'Linux':
return new Linux();
case 'NetBSD':
return new NetBsd();
case 'OpenBSD':
return new OpenBsd();
case 'SunOS':
return new Solaris();
case 'Unix':
return new Unix();
case 'WIN32':
return new Win32();
case 'WINNT':
return new WinNT();
case 'Windows':
case 'Windows XP 64-bit':
return new Win64();
case 'OS/2 Warp':
return new Os2();
case 'eComStation':
return new EComStation();
case 'RISC OS':
return new RiscOs();
}
return new UnknownOs();
}
/**
* Gets whether running operating system is unix based.
*
* @return boolean true if the system is unix based
*/
abstract public function isUnix();
/**
* Gets whether running operating system is windows based.
*
* @return boolean true if the system is windows based
*/
abstract public function isWindows();
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* Os2 class file.
*
* This class represents an operating system of the OS/2 family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/OS/2
*/
class Os2 extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return false;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* RiscOs class file.
*
* This class represents an operating system of the RISC OS family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/RISC_OS
*/
class RiscOs extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return false;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* Solaris class file.
*
* This class represents an operating system of the Solaris family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/Solaris_(operating_system)
*/
class Solaris extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return true;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace PhpExtended\System;
/**
* Unix class file.
*
* This class represents a metaclass that represents all operating systems that
* comply with the linux family and that are not treated as a separate family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/Unix
*/
class Unix extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return true;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php
namespace PhpExtended\System;
/**
* UnknownOs class file.
*
* This class represents an Os this library was not able to detect.
*
* @author Anastaszor
*/
class UnknownOs extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return false;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* Win32 class file.
*
* This class represents an operating system of the windows x86 family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/Microsoft_Windows
*/
class Win32 extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return false;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return true;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* Win64 class file.
*
* This class represents an operating system of the windows x64 family.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/Microsoft_Windows
*/
class Win64 extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return false;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return true;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace PhpExtended\System;
/**
* WinNT class file.
*
* This class represents an operating system on the windows NT kernel.
*
* @author Anastaszor
* @see https://en.wikipedia.org/wiki/Microsoft_Windows
*/
class WinNT extends OperatingSystem
{
/**
* {@inheritDoc}
*
* @see OperatingSystem::isUnix()
*/
public function isUnix()
{
return false;
}
/**
* {@inheritDoc}
*
* @see OperatingSystem::isWindows()
*/
public function isWindows()
{
return false;
}
}
+12
View File
@@ -0,0 +1,12 @@
composer.phar
composer.lock
/vendor/
# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
# composer.lock
# eclipse crap
.settings/
.buildpath
.project
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+62
View File
@@ -0,0 +1,62 @@
# php-tail
A smart way to tail files depending of the environment
## Installation
The installation of this library is made via composer.
Download `composer.phar` from [their website](https://getcomposer.org/download/).
Then add to your composer.json :
```json
"require": {
...
"php-extended/php-tail": "^2.0",
...
}
```
Then run `php composer.phar update` to install this library.
The autoloading of all classes of this library is made through composer's autoloader.
## Usage
The basic usage of this library is as follows :
```php
use PhpExtended\Tail\Tail;
use PhpExtended\Tail\TailException;
$filename = "/../path/to/my/file.ext";
$tail = new Tail($filename);
try
{
// 10 is the number of lines you want
// 200 is the average number of chars on each line (optional)
// false is to force throwing exceptions (optional, use true if you want silent mode)
$lines = $tail->smart(10, 200, false);
}
catch(TailException $e)
{
// do something is case it fails
}
```
This library proposes 6 methods to tail a file, which can be more or less
performant depending on the context. They each follow the same signature
(see sample code above).
Those methods are :
- `naive` : Loads the whole file into php, then retains only the last lines
- `cheat` : Uses underlying unix `tail -n` function
- `single` : Uses a signle byte buffer to read backwards the file
- `simple` : Uses a fixed size buffer to read backwards the file
- `dynamic` : Uses a dynamically sized buffer to read backwards the file
- `smart` : Tries to choose the best among those five to be the fastest (recommanded)
This library is inspired from this [specific stackoverflow topic](http://stackoverflow.com/questions/15025875/what-is-the-best-way-in-php-to-read-last-lines-from-a-file/15025877).
## License
MIT (See [license file](LICENSE)).
+31
View File
@@ -0,0 +1,31 @@
{
"name" : "php-extended/php-tail",
"description" : "A smart way to tail files depending of the environment",
"type" : "library",
"license" : "MIT",
"authors" : [{
"name" : "Anastaszor",
"role" : "Developer"
}
],
"support" : {
"issues" : "https://github.com/php-extended/php-tail/issues",
"source" : "https://github.com/php-extended/php-tail"
},
"keywords" : [
"php",
"tail",
"naive",
"cheat",
"mighty"
],
"autoload" : {
"psr-4" : {
"PhpExtended\\Tail\\" : "src/"
}
},
"homepage" : "https://github.com/php-extended/php-tail",
"require" : {
"php-extended/php-system" : "^1.2"
}
}
@@ -0,0 +1,32 @@
<?php
namespace PhpExtended\Tail;
/**
* FileNotFoundException class file.
*
* This exception represents a target error when the file was designed because
* the path it represents is not pointing on a file. This exception is also
* thrown if the given path is pointing on a directory or a symlink, or
* anything else that is not a file.
*
* @author Anastaszor
*/
class FileNotFoundException extends TailException
{
/**
* Builds a new FileNotFoundException object.
*
* @param string $filename the name of targeted file
* @param int $nblines the number of lines that were demanded
* @param int $hint an estimation of the line length in that file
*/
public function __construct($filename, $nblines, $hint)
{
parent::__construct($filename, $nblines, $hint,
strtr('The file "{file}" does not exists.', array('{file}' => $filename)),
404
);
}
}
@@ -0,0 +1,32 @@
<?php
namespace PhpExtended\Tail;
/**
* FileTooBigExcepion class file.
*
* This exception represents a try to read on a file that is larger than the
* int max capacity on the system. This exception may occur if the file length
* exceeds the INT32 capacity on windows 32 bits systems. It should not occur
* on 64 bits php (except if the size is larger than 2^63 bytes)
*
* @author Anastaszor
*/
class FileTooBigException extends TailException
{
/**
* Builds a new FileTooBigException object.
*
* @param string $filename the name of targeted file
* @param int $nblines the number of lines that were demanded
* @param int $hint an estimation of the line length in that file
*/
public function __construct($filename, $nblines, $hint)
{
parent::__construct($filename, $nblines, $hint,
strtr('File {filename} is too big to be read.', array('{filename}' => $filename)),
500
);
}
}
+30
View File
@@ -0,0 +1,30 @@
<?php
namespace PhpExtended\Tail;
/**
* IOException class file.
*
* This exception represents a read error on targeted file that occured during
* the reading process of tail.
*
* @author Anastaszor
*/
class IOException extends TailException
{
/**
* Builds a new IOException object.
*
* @param string $filename the name of targeted file
* @param int $nblines the number of lines that were demanded
* @param int $hint an estimation of the line length in that file
*/
public function __construct($filename, $nblines, $hint)
{
parent::__construct($filename, $nblines, $hint,
strtr('Error in reading file {filename}', array('{filename}' => $filename)),
500
);
}
}
@@ -0,0 +1,30 @@
<?php
namespace PhpExtended\Tail;
/**
* IllegalArgumentException class file.
*
* This exception is thrown when the number of lines that was asked is negative
* or null.
*
* @author Anastaszor
*/
class IllegalArgumentException extends TailException
{
/**
* Builds a new IllegalArgumentException object.
*
* @param string $filename the name of targeted file
* @param int $nblines the number of lines that were demanded
* @param int $hint an estimation of the line length in that file
*/
public function __construct($filename, $nblines, $hint)
{
parent::__construct($filename, $nblines, $hint,
strtr('Error in reading file {filename}', array('{filename}' => $filename)),
500
);
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
namespace PhpExtended\Tail;
/**
* IllegalOsException class file.
*
* This exception is thrown when the cheating method to tail a file, i.e.
* calling the tail unix function is choosen, but the running operating system
* is not supporting that function.
*
* @author Anastaszor
*/
class IllegalOsException extends TailException
{
/**
* Builds a new IllegalOsException object.
*
* @param string $filename the name of targeted file
* @param int $nblines the number of lines that were demanded
* @param int $hint an estimation of the line length in that file
*/
public function __construct($filename, $nblines, $hint)
{
parent::__construct($filename, $nblines, $hint,
'You can\'t try to call unix\'s tail function on a non unix system.',
500
);
}
}
@@ -0,0 +1,31 @@
<?php
namespace PhpExtended\Tail;
/**
* OutputBufferException class file.
*
* This exception is thrown when the cheating method is called and something
* went wrong with the output buffers. This usually means that the output
* buffer stack is full, or the ob library is not loaded.
*
* @author Anastaszor
*/
class OutputBufferException extends TailException
{
/**
* Builds a new OutputBufferException object.
*
* @param string $filename the name of targeted file
* @param int $nblines the number of lines that were demanded
* @param int $hint an estimation of the line length in that file
*/
public function __construct($filename, $nblines, $hint)
{
parent::__construct($filename, $nblines, $hint,
"Error when using the output buffer.",
500
);
}
}
+512
View File
@@ -0,0 +1,512 @@
<?php
namespace PhpExtended\Tail;
use PhpExtended\System\OperatingSystem;
/**
* Tail class file.
*
* This class provides methods that tails given file and return an array with
* the wanted final lines of that file.
* This class is the equivalent of a `tail -n X filepath` unix command.
*
* @author Anastaszor
* @see http://stackoverflow.com/questions/15025875/what-is-the-best-way-in-php-to-read-last-lines-from-a-file/15025877
*/
class Tail
{
/**
* If true, the given file should exists. This does not guarantee that
* that file will remain existant for as long as the tailing process will
* need it to be.
*
* @var boolean whether the given file exists.
*/
private $_file_exists = null;
/**
* The path to the file. If it is a relative path, then all the process
* for finding files with fopen() will be used, and this library does not
* modify any of that configuration.
*
* @var string the path of targeted file.
*/
private $_file_path = null;
/**
* Builds a new Tail object on targeted file path. If targeted file path
* does not exists, the object will still be correcly constructed. Check
* the <code>getFileExists()</code> method to be safe as tailing targeted
* file.
*
* @param string $filepath the targeted file path, may be absolute or
* relative, all rules for finding it with fopen will be unchanged.
*/
public function __construct($filepath)
{
$this->_file_path = $filepath;
$this->_file_exists = is_file($this->_file_path);
}
/**
* Gets the file path that was given to this object.
*
* @return string the file path of the target.
*/
public function getFilePath()
{
return $this->_file_path;
}
/**
* Gets whether target file exists or not.
*
* @return boolean
*/
public function getFileExists()
{
return $this->_file_exists;
}
/**
* Gets whether this running system is from an unix family. This is called
* only assuming that ALL linux based operating system have the tail -n
* command available and in their $PATH, so it can direcly be called by
* php's passthru() function.
*
* @return boolean true if `tail -n` is supported.
*/
protected function isUnixSystem()
{
return OperatingSystem::get()->isUnix();
}
/**
* Decides the best way to tail the given file given the environment.
*
* @param int $nblines the number of lines wanted
* @param int $hint a median number of bytes for each line in target file
* @param boolean $silent if false, any error will throw an exception. If
* true, any error will silently return an empty array.
* @return string[] the wanted tailed lines
*/
public function smart($nblines, $hint = null, $silent = false)
{
if(!$this->_file_exists)
{
if($silent) return array();
throw new FileNotFoundException($this->_file_path, $nblines, $hint);
}
$nblines = (int) $nblines;
if($nblines <= 0)
{
if($silent) return array();
throw new IllegalArgumentException($this->_file_path, $nblines, $hint);
}
$filelength = @filesize($this->_file_path);
if($filelength === false)
{
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
if($filelength == 0)
return array();
if($filelength < 0)
{
if($this->isUnixSystem())
return $this->cheat($nblines, $hint, $silent);
if($silent) return array();
throw new FileTooBigException($this->_file_path, $nblines, $hint);
}
if($nblines <= 2)
return $this->single($nblines, $hint, $silent);
if($filelength <= 10240) // 10kB
return $this->naive($nblines, $hint, $silent);
return $this->dynamic($nblines, $hint, $silent);
}
/**
* The naive approach. This will load the whole file into php's buffer
* and extract only the last wanted lines.
*
* @param int $nblines the number of lines wanted
* @param int $hint a median number of bytes for each line in target file
* @param boolean $silent if false, any error will throw an exception. If
* true, any error will silently return an empty array.
* @return string[] the wanted tailed lines
*/
public function naive($nblines, $hint = null, $silent = false)
{
if(!$this->_file_exists)
{
if($silent) return array();
throw new FileNotFoundException($this->_file_path, $nblines, $hint);
}
$nblines = (int) $nblines;
if($nblines <= 0)
{
if($silent) return array();
throw new IllegalArgumentException($this->_file_path, $nblines, $hint);
}
$filedata = file($this->_file_path);
if($filedata === false)
{
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
return array_slice($filedata, -$nblines);
}
/**
* The cheating approach. This will call the tail unix function and get
* the return from it.
*
* @param int $nblines the number of lines wanted
* @param int $hint a median number of bytes for each line in target file
* @param boolean $silent if false, any error will throw an exception. If
* true, any error will silently return an empty array.
* @return string[] the wanted tailed lines
*/
public function cheat($nblines, $hint = null, $silent = false)
{
if(!$this->_file_exists)
{
if($silent) return array();
throw new FileNotFoundException($this->_file_path, $nblines, $hint);
}
$nblines = (int) $nblines;
if($nblines <= 0)
{
if($silent) return array();
throw new IllegalArgumentException($this->_file_path, $nblines, $hint);
}
if(!$this->isUnixSystem())
{
if($silent) return array();
throw new IllegalOsException($this->_file_path, $nblines, $hint);
}
if(!function_exists('ob_start'))
{
if($silent) return array();
throw new OutputBufferException($this->_file_path, $nblines, $hint);
}
if(!ob_start())
{
if($silent) return array();
throw new OutputBufferException($this->_file_path, $nblines, $hint);
}
$returnvar = 0;
passthru('tail -n '.$nblines.' '.escapeshellarg($this->_file_path), $returnvar);
if($returnvar !== 0)
{
ob_end_clean();
if($silent) return array();
throw new TailShellException($this->_file_path, $nblines, $hint, $returnvar);
}
$results = ob_get_clean();
if($results === false)
{
if($silent) return array();
throw new OutputBufferException($this->_file_path, $nblines, $hint);
}
return array_map('trim', explode("\n", $results));
}
/**
* The single byte buffer approach. This will read backward from the end
* of the file each char until wanted lines are read.
*
* @param int $nblines the number of lines wanted
* @param int $hint a median number of bytes for each line in target file
* @param boolean $silent if false, any error will throw an exception. If
* true, any error will silently return an empty array.
* @return string[] the wanted tailed lines
*/
public function single($nblines, $hint = null, $silent = false)
{
if(!$this->_file_exists)
{
if($silent) return array();
throw new FileNotFoundException($nblines, $hint);
}
$nblines = (int) $nblines;
if($nblines <= 0)
{
if($silent) return array();
throw new IllegalArgumentException($this->_file_path, $nblines, $hint);
}
$handle = fopen($this->_file_path, 'r');
if($handle === false)
{
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
$linecounter = $nblines;
$pos = -2;
$beginning = false;
$text = array();
while($linecounter > 0)
{
$t = " ";
while($t != "\n")
{
$seek = fseek($handle, $pos, SEEK_END);
if($seek === -1)
{
$beginning = true;
break;
}
$t = fgetc($handle);
if($t === false)
{
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
$pos--;
}
$linecounter--;
if($beginning)
{
$rewind = rewind($handle);
if($rewind === false)
{
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
}
$data = fgetc($handle);
if($data === false)
{
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
$text[$nblines - $linecounter - 1] = $data;
if($beginning) break;
}
fclose($handle);
return array_reverse($text);
}
/**
* The simple buffer approach. This will read backward from the end of the
* file with a fixed size buffer until wanted lines are read.
*
* @param int $nblines the number of lines wanted
* @param int $hint a median number of bytes for each line in target file
* @param boolean $silent if false, any error will throw an exception. If
* true, any error will silently return an empty array.
* @return string[] the wanted tailed lines
*/
public function simple($nblines, $hint = null, $silent = false)
{
if(!$this->_file_exists)
{
if($silent) return array();
throw new FileNotFoundException($nblines, $hint);
}
$nblines = (int) $nblines;
if($nblines <= 0)
{
if($silent) return array();
throw new IllegalArgumentException($this->_file_path, $nblines, $hint);
}
if($hint === null)
{
// just assuming that this is text file with 40 char per line as a
// median basis. May be larger if it is a log file
$hint = 40;
if(strrpos($this->_file_path, '.log') === strlen($this->_file_path) - 4)
{
$hint = 240;
}
}
$buffer = 4096;
return $this->find($nblines, $buffer, $hint, $silent);
}
/**
* The dynamic buffer approach. This will read backward from the end of the
* file with a fixed size buffer which is proportional to the size of the
* wanted chunk of that file.
*
* @param int $nblines the number of lines wanted
* @param int $hint a median number of bytes for each line in target file
* @param boolean $silent if false, any error will throw an exception. If
* true, any error will silently return an empty array.
* @return string[] the wanted tailed lines
*/
public function dynamic($nblines, $hint = null, $silent = false)
{
if(!$this->_file_exists)
{
if($silent) return array();
throw new FileNotFoundException($nblines, $hint);
}
$nblines = (int) $nblines;
if($nblines <= 0)
{
if($silent) return array();
throw new IllegalArgumentException($this->_file_path, $nblines, $hint);
}
if($hint === null)
{
// just assuming that this is text file with 40 char per line as a
// median basis. May be larger if it is a log file
$hint = 40;
if(strrpos($this->_file_path, '.log') === strlen($this->_file_path) - 4)
{
$hint = 240;
}
}
$buffer = $hint * $nblines / 10;
return $this->find($nblines, $buffer, $hint, $silent);
}
/**
* Extracts the wanted number of lines according to the given buffer
* length.
*
* @param int $nblines the number of lines wanted
* @param int $buffer the size of the buffer that will be used to seek
* @param int $hint an estimation of the median line length on this file
* @param boolean $silent if false, any error will throw an exception.
* If true, any error will silently return an empty array.
* @return string[] the wanted tailed lines
* @throws IOException if any error occur
*/
protected function find($nblines, $buffer, $hint, $silent)
{
$lines = $nblines;
$f = fopen($this->_file_path, 'r');
if($f === false)
{
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
$seek = fseek($f, -1, SEEK_END);
if($seek === -1)
{
fclose($f);
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
$read = fread($f, 1);
if($read === false)
{
fclose($f);
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
if($read === "\n") $lines -= 1;
// faster initialisation
$seek = min(ftell($f), $hint * $nblines);
$seeked = fseek($f, -$seek, SEEK_CUR);
if($seeked === -1)
{
fclose($f);
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
$chunk = fread($f, $seek);
if($chunk === false)
{
fclose($f);
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
$output = $chunk;
$seeked = fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR);
if($seeked === -1)
{
fclose($f);
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
$lines -= substr_count($chunk, "\n");
// while we want more
while(ftell($f) > 0 && $lines >= 0)
{
// figure out how far back we should jump
$seek = min(ftell($f), $buffer);
// do the jump backwards relative to where we are
$seeked = fseek($f, -$seek, SEEK_CUR);
if($seeked === -1)
{
fclose($f);
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
// read a chunk and prepend it to out output
$chunk = fread($f, $seek);
if($chunk === false)
{
fclose($f);
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
$output = $chunk . $output;
// jump back to where we started reading
$seeked = fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR);
if($seeked === -1)
{
fclose($f);
if($silent) return array();
throw new IOException($this->_file_path, $nblines, $hint);
}
// decrease out line counter
$lines -= substr_count($chunk, "\n");
}
fclose($f);
// while we have too many lines
// because the buffer size we might have read too many
while($lines++ < 0)
{
$output = substr($output, strpos($output, "\n") + 1);
}
return explode("\n", str_replace(array("\r\n", "\r"), array("\n", ''), trim($output)));
}
}
+84
View File
@@ -0,0 +1,84 @@
<?php
namespace PhpExtended\Tail;
/**
* TailException class file.
*
* This is a generic purpose exception for all of that may occur when tailing
* a file with this library.
*
* @author Anastaszor
*/
class TailException extends \Exception
{
/**
* The path of the file that was given.
*
* @var string the path of the file.
*/
private $_filename = null;
/**
* The number of lines that were asked.
*
* @var int the number of lines.
*/
private $_nblines = null;
/**
* An estimation of the number of characters per line.
*
* @var int the median number of characters per line.
*/
private $_hint = null;
/**
* Builds a new TailException object.
*
* @param string $filename the name of the file
* @param int $nblines the number of lines wanted
* @param int $hint an estimation of the median number of characters per line
* @param string $message the message of the exception
* @param int $code the error code associated to this exception
*/
public function __construct($filename, $nblines, $hint, $message, $code)
{
parent::__construct($message, $code);
$this->_filename = $filename;
$this->_nblines = $nblines;
$this->_hint = $hint;
}
/**
* Gets the file path that was asked.
*
* @return string
*/
public function getFilename()
{
return $this->_filename;
}
/**
* Gets the number of lines that was asked.
*
* @return int
*/
public function getNblines()
{
return $this->_nblines;
}
/**
* Gets the median number of characters per line that was given, or
* calculated, if applicable.
*
* @return int
*/
public function getHint()
{
return $this->_hint;
}
}
+30
View File
@@ -0,0 +1,30 @@
<?php
namespace PhpExtended\Tail;
/**
* TailShellException class file.
*
* This exception occurred if the `tail -n` command on an unix shell did not
* return the expected result.
*
* @author Anastaszor
*/
class TailShellException extends TailException
{
/**
* Builds a new TailShellException object.
*
* @param string $filename the name of targeted file
* @param int $nblines the number of lines that were demanded
* @param int $hint an estimation of the line length in that file
*/
public function __construct($filename, $nblines, $hint)
{
parent::__construct($filename, $nblines, $hint,
strtr('Error in reading file {filename}', array('{filename}' => $filename)),
500
);
}
}