Calculate subdirectory size of a directory (PHP) - php

I have a folder that contains subfolders of years (e.g. 2011, 2012 etc.). Each year's folder contains month folders (e.g 02, 09 etc).
How do I calculate the total size of the month folders and list them along with the year and month folder names?
Example:
Directory Name - Size
06/2008 - 52KB
10/2010 - 151MB
27/2012 - 852MB
12/01/2013 - 5GB
Cheers.

You can try
echo "<pre>";
$depth = 1;
$ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST);
$r = array();
foreach ( $ritit as $splFileInfo ) {
if ($ritit->getDepth() === $depth && $splFileInfo->isDir()) {
printf("%s - %s \n", $splFileInfo, getSize($splFileInfo));
}
}
function getSize($dir, $precision = 2) {
$ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS));
$bytes = 0;
foreach ( $ritit as $v ) {
$bytes += $v->getSize();
}
$units = array('B','KB','MB','GB','TB');
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
You can also try this approach using FilterIterator
$depth = 1;
$it = new RecursiveDirectoryIterator("./", RecursiveDirectoryIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::SELF_FIRST);
$it = new FileDepthFilterIterator($it, $depth, FileDepthFilterIterator::ONLY_DIR);
foreach ( $it as $splFileInfo ) {
printf("%s\n", new RecusiveSizeInfo($splFileInfo));
}
Classes used
class FileDepthFilterIterator extends FilterIterator {
private $it;
private $depth;
private $type;
const ONLY_DIR = 1;
const ONLY_FILE = 2;
const BOTH_DIR_FILE = 3;
function __construct(RecursiveIteratorIterator &$iterator, $depth, $type) {
$this->it = &$iterator;
$this->depth = $depth;
$this->type = $type;
parent::__construct($this->it);
}
function accept() {
if ($this->getDepth() != $this->depth) {
return false;
}
if ($this->type == self::ONLY_DIR && ! $this->getInnerIterator()->current()->isDir()) {
return false;
}
if ($this->type == self::ONLY_FILE && ! $this->getInnerIterator()->current()->isFile()) {
return false;
}
return true;
}
}
class RecusiveSizeInfo {
/**
*
* #var SplFileInfo
*/
private $info;
private $numFiles = 0;
private $numFolder = 0;
private $bytes = 0;
function __construct(SplFileInfo $info) {
$this->info = $info;
$this->parse();
}
public function getNumFiles() {
return $this->numFiles;
}
public function getNumFolder() {
return $this->numFolder;
}
public function getBytes() {
return $this->bytes;
}
public function __toString() {
return sprintf("%s\t%s\t%s", $this->info, $this->formatSize($this->getBytes()), json_encode(array("file" => $this->numFiles,"dir" => $this->numFolder)));
}
private function parse() {
$ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->info , RecursiveDirectoryIterator::SKIP_DOTS),RecursiveIteratorIterator::SELF_FIRST);
foreach ( $ritit as $v ) {
$v->isFile() and $this->numFiles ++;
$v->isDir() and $this->numFolder ++;
$this->bytes += $v->getSize();
}
}
private function formatSize($bytes) {
$units = array('B','KB','MB','GB','TB');
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, 2) . ' ' . $units[$pow];
}
}

Look at this answer to work out the size of directories. To implement, you're going to need to traverse your directory structure recursively, or manually specify the directories you want:
<li>2012/01 <?php echo foldersize('/2012/01'); ?></li>
<li>2012/02 <?php echo foldersize('/2012/01'); ?></li>

Related

phpcs: How to enforce class inheritance?

I want to make sure all classes in some dir (src/Controller/CP) extend some other class AbstractCPController.
So that
class SupportTicketTagController extends AbstractController
would show PHPCS error, and
class SupportTicketTagController extends AbstractCPController
would be fine.
Is that possible with PHPCS?
I ended up creating my own Sniff. Its far from perfect but may serve as a base for somebody in the future:
<?php
declare(strict_types=1);
namespace MyCodingStandard\Sniffs\Classes;
use PHP_CodeSniffer\Fixer;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Files\File;
/**
* Sniff for catching classes not marked as abstract or final
*/
final class ClassInheritanceSniff implements Sniff
{
private ?Fixer $fixer;
private $position;
public function register(): array
{
return [T_CLASS];
}
public function process(File $file, $position): void
{
$this->fixer = $file->fixer;
$this->position = $position;
$tokens = $file->getTokens();
$className = $tokens[$file->findNext(T_STRING, $position + 1)]['content'];
if ($className === 'AbstractCPController') {
return;
}
$curlyOpenLine = $file->findNext(T_OPEN_CURLY_BRACKET, $position + 1);
$extendsLine = $file->findNext(T_EXTENDS, $position + 1, $curlyOpenLine - 1);
$implementsLine = $file->findNext(T_IMPLEMENTS, $position + 1, $curlyOpenLine - 1);
$extendedClasses = [];
$implementedInterfaces = [];
if ($extendsLine) {
$extendsLineMax = $curlyOpenLine - 1;
if ($implementsLine > $extendsLine) {
$extendsLineMax = $implementsLine - 1;
}
$lastClassName = '';
for ($i = $extendsLine + 1; $i < $extendsLineMax; $i++) {
if ($tokens[$i]['code'] == T_STRING || $tokens[$i]['code'] == T_NS_SEPARATOR) {
$lastClassName .= $tokens[$i]['content'];
} else {
if ($lastClassName) {
$extendedClasses[] = $lastClassName;
$lastClassName = '';
}
}
}
if ($lastClassName) {
$extendedClasses[] = $lastClassName;
}
}
if ($implementsLine) {
$implementsLineMax = $curlyOpenLine - 1;
if ($extendsLine > $implementsLine) {
$implementsLineMax = $extendsLine - 1;
}
$lastClassName = '';
for ($i = $implementsLine + 1; $i < $implementsLineMax; $i++) {
if ($tokens[$i]['code'] == T_STRING || $tokens[$i]['code'] == T_NS_SEPARATOR) {
$lastClassName .= $tokens[$i]['content'];
} else {
if ($lastClassName) {
$implementedInterfaces[] = $lastClassName;
$lastClassName = '';
}
}
}
if ($lastClassName) {
$implementedInterfaces[] = $lastClassName;
}
}
foreach ($extendedClasses as $class) {
if (str_ends_with($class, 'AbstractCPController')) {
return;
}
}
$file->addError(
'All CP Controller classes should extend from AbstractCPController',
$position - 1,
self::class
);
}
}

Add element to listnode in PHP

If i have a listnode with the following defination
class ListNode {
public $val = 0;
public $next = null;
function __construct($val = 0, $next = null) {
$this->val = $val;
$this->next = $next;
}
}
How can i add an element to the end of the listnode and thus add int[i] elements by interation?
class ListNode {
public int $val = 0;
public ?ListNode $next = null;
function __construct(?int $val = 0, ?ListNode $next = null) {
$this->val = $val;
$this->next = $next;
}
function appendToListEnd(int $val) {
if ($this->next == null) {
$this->next = new ListNode($val);
} else {
$temp = $this->next;
while ($temp->next != null) {
$temp = $temp->next;
}
$temp->next = new ListNode($val);
}
}
}
$arr = [ 1, 2, 3, 4 ];
$listHead = new ListNode($arr[0]);
for ($i = 1; $i < count($arr); $i++) {
$listHead->appendToListEnd($arr[$i]);
}
print_r($listHead);
$listHead->appendToListEnd(5);
print_r($listHead);

PHP Convert TRON Hex address to Base58

Based on the official TRON documentation, they have API based on TRONWEB to work with Javascript.
https://developers.tron.network/reference#address
However I'm working on a backend PHP app and would like to store TRON address as Base58 instead of hex FORMAT (Default is HEX in API outputs)
So is there any way to convert the address from HEX to Base58 in PHP?
(Have researched and couldn't find any possible answer already)
Just use following functions:
function base58_decode($base58)
{
$alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
$base = strlen($alphabet);
if (is_string($base58) === false) {
return false;
}
if (strlen($base58) === 0) {
return '';
}
$indexes = array_flip(str_split($alphabet));
$chars = str_split($base58);
foreach ($chars as $char) {
if (isset($indexes[$char]) === false) {
return false;
}
}
$decimal = $indexes[$chars[0]];
for ($i = 1, $l = count($chars); $i < $l; $i++) {
$decimal = bcmul($decimal, $base);
$decimal = bcadd($decimal, $indexes[$chars[$i]]);
}
$output = '';
while ($decimal > 0) {
$byte = bcmod($decimal, 256);
$output = pack('C', $byte) . $output;
$decimal = bcdiv($decimal, 256, 0);
}
foreach ($chars as $char) {
if ($indexes[$char] === 0) {
$output = "\x00" . $output;
continue;
}
break;
}
return $output;
}
function base58check_de($base58add)
{
$address = base58_decode($base58add);
$size = strlen($address);
if ($size != 25) {
return false;
}
$checksum = substr($address, 21);
$address = substr($address, 0, 21);
$hash0 = hash("sha256", $address);
$hash1 = hash("sha256", hex2bin($hash0));
$checksum0 = substr($hash1, 0, 8);
$checksum1 = bin2hex($checksum);
if (strcmp($checksum0, $checksum1)) {
return false;
}
return $address;
}
If you need more functionality then take a look at this.
Yes, It's possible to do the conversion in php.
First, install the package iexbase/tron-api via composer.
How I do mine is, I have a class called Address and it looks like:
<?php
namespace App\EventHandlers\Param;
use Web3\Utils;
class Address extends Base
{
private $hex;
private $base58;
public function __construct(string $address)
{
$this->tron = $this->getTron();
if ($address === '0x0000000000000000000000000000000000000000' || $address === 'T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb') {
$this->hex = null;
$this->base58 = null;
} else {
if (Utils::isHex($address)) {
if (substr($address, 0, 2) === '0x') {
//set prefix
$address = '41'.substr($address, 2);
}
$this->hex = $address;
$this->base58 = $this->tron->hexString2Address($address);
} else {
$this->base58 = $address;
$this->hex = $this->tron->address2HexString($address);
}
}
}
public function getHex()
{
return $this->hex;
}
public function getBase58()
{
return $this->base58;
}
public function __toString()
{
return json_encode(['hex' => $this->hex, 'base58' => $this->base58]);
}
}
This Address class extends a Base class which helps with setting up an instance of the Tron API client. The Base class looks like:
<?php
namespace App\EventHandlers\Param;
use IEXBase\TronAPI\Tron;
use IEXBase\TronAPI\Provider\HttpProvider;
use IEXBase\TronAPI\Exception\TronException;
class Base
{
/**
* #var Tron
*/
protected $tron;
/**
* #return Tron
* #throws TronException
*/
public function getTron():?Tron
{
$fullNode = new HttpProvider(config('tron.full_node'));
$solidityNode = new HttpProvider(config('tron.solidity_node'));
$eventServer = new HttpProvider(config('tron.event_server'));
try {
return new Tron($fullNode, $solidityNode, $eventServer);
} catch (TronException $exception) {
return null;
}
}
}
So you can then do
$address = new Address($hexOrBase58Address);
then access the address in whatever format:
$address->getHex(); // Gives the hex address
or
$address->getBase58(); //Gives the base58 address
I really hope this helps you.

Convert binary bytes to string

what im trying to do:
1. uncompress compressed file.
2.insert the uncompressed file bytes into array.
3.convert each byte to chr.
the code:
<?php
$list = file_get_contents('http://www.getlist.xp3.biz/list3'); //get the contents of the compressed file
$list = gzuncompress($list); //Uncompress the file
$bytes = unpack('c*', $list); //unpack the bytes of list into array
$string = implode('', array_map('chr', $bytes)); //convert each byte to chr by implode and array_map functions
echo $string; //print results
?>
this code is almost works.
the results:
http://getlist.xp3.biz/getlist.php
lets take this line for example:
B~12ee397313ba2dd4f27fc1430744e615e4f83a44f9b206fb78fdf9b45dd9dc74fel profanador88's Room ar�7t��Bk
in the end of the line there are some wired chars : ar�7t��Bk
this chars are not text byte, someone(other developer) is converted the bytes and his php file returns the line with more information:
{"ver":"26","id":"12ee397313ba2dd4f27fc1430744e615e4f83a44f9b206fb78fdf9b45dd9dc74f","name":"profanador88's Room","players":"1","max_players":"10","password":false,"country":"ar","latitude":"41.0186004639","longitude":"28.9647006989","distance":1168.7633}
i have the id ,roomname and country code(and the werid chars(=the other info)).
in his line: version,id, name ,players number,max player number,if isset password(boolean),contry code, latitude,longitude and distance.
exactly 7 more.
maybe ar�7t��Bk contains the other information?
i think that the other info is there (100%), i just dont know how to convert the bytes(of the werid chars).
i tried to ask the other developer about this werid chars but there is no answer.
maybe someone know how to convert this binary file into normal string,
maybe this information can help(the note of the other developer):
the list is a compressed binary file
which you can obtain # /list3
it is compressed with zlib deflate
after decompression the format is as follows: (wait a bit must open the source file)
1 byte ; list format version ( currently = 1 )
4 bytes ; skip this, you don't care about them
then follows a list of RoomInfo structures until the end of the file
this is the Roominfo structure:
data.writeShort(ver); //Vrsion Short
data.writeUTF(netID); //ID String
data.writeUTF(name); //ROOMNAME string
data.writeByte(players); //PLAYERS
data.writeByte(maxPlayers); //MaxPlayers
data.writeBoolean(password); //If isset password boolean
data.writeUTF(countryCode); //country code
data.writeFloat(latitude); //Float latitude
data.writeFloat(longitude); //Float longitude
that's all
im using chr function to convert the bytes into big string, hi says that the byte are not only strings, there are bytes that represent:Float,Boolean,Integer,Short.
chr is to bytes that represent string only(and i used it : $string = implode('', array_map('chr', $bytes)); ), there im worng maybe i need to read each byte by foreach without using this shortcut.
my question is:
Does anyon know how to fix the code and make it work(make the php print the other info that missing(the info is there , but in bytes(not of string)))?
UPDATE:
i think that i found the class that converts byte to short/boolean/float/integer ,
now i need that someone explain to me how to use this class (require('class.php')...code here), or someone will try to fix my code with this class(im trying to fix it alone but i still dont know how to use this lib or when i need to use the lib).
the class:
class ByteArray{
private $BytesString;
function ByteArray($bytes = "") {
$this->BytesString = $bytes;
}
function writeBoolean($value = 1) {
$this->BytesString .= $this->writeByte($value, False);
}
function writeByte($value, $noReturning=True) {
if ($noReturning) $this->BytesString .= pack("C", $value);
else return pack("C", $value);
}
function writeBytes($value) {
$this->BytesString .= $value;
}
function writeInt($value) {
$this->BytesString .= pack('N', $value);
}
function writeShort($value) {
$this->BytesString .= pack('n', $value);
}
function writeUTF($value) {
$valueSize = strlen($value);
$this->writeShort($valueSize);
$this->writeUTFBytes($value);
}
function writeUTFBytes($value) {
$this->BytesString .= $value;
}
function length() {
return strlen($this->BytesString);
}
function toString() {
return $this->BytesString;
}
function toPack() {
$value = pack('N', strlen($this->BytesString)+4);
return $value.$this->BytesString;
}
function getSize() {
$value = unpack('N', substr($this->BytesString, 0, 4));
return $value[1];
}
function readBy($Pos) {
$this->BytesString = substr($this->BytesString, $Pos);
return $this->BytesString;
}
function loc($byte) {
$loc = substr($this->BytesString, 0, $byte);
$this->BytesString = substr($this->BytesString, $byte);
return unpack('C', $loc);
}
function readInt() {
$size = unpack('N', substr($this->BytesString, 0, 4)); $size = $size[1];
$this->BytesString = substr($this->BytesString, 4);
return $size;
}
function readUTF() {
$size = unpack('n', substr($this->BytesString, 0, 2)); $size = $size[1];
$string = substr($this->BytesString, 2, $size);
$this->BytesString = substr($this->BytesString, $size + 2);
return $string;
}
function readShort() {
$size = unpack('n', substr($this->BytesString, 0, 2)); $size = $size[1];
$this->BytesString = substr($this->BytesString, 2);
return $size;
}
function readBoolean() {
$loc = unpack('C', substr($this->BytesString, 0, 1)); $loc = $loc[1];
$this->BytesString = substr($this->BytesString, 1);
if ($loc == 1) return True;
else return False;
}
function readByte() {
$byte = unpack('C', substr($this->BytesString, 0, 1)); $byte = $byte[1];
$this->BytesString = substr($this->BytesString, 1);
return $byte;
}
}
UPDATE2:
version 2 of the class, if the first not working
<?php
class ByteArray {
protected $bigEndian = TRUE;
protected $byteArray;
protected $capacity;
protected $limit;
protected $mark;
public $position;
public function __construct($byteArray = '') {
$this->byteArray = $byteArray;
$this->position = 0;
$this->mark = - 1;
$this->init ();
}
private function init() {
$this->capacity = strlen ( $this->byteArray );
$this->limit = $this->capacity;
}
public function _array() {
return $this->byteArray;
}
public function clear() {
$this->limit = $this->capacity;
$this->position = 0;
$this->mark = - 1;
}
private function get($length = null) {
if ($length === null) {
$length = $this->limit - $this->position;
} elseif ($length > $this->bytesAvailable ()) {
throw new Exception ( 'bytesAvailable' );
}
$data = substr ( $this->byteArray, $this->position, $length );
$this->position += $length;
return $data;
}
private function set($bytes) {
$p1 = substr ( $this->byteArray, 0, $this->position );
$p2 = substr ( $this->byteArray, $this->position );
$len = strlen ( $bytes );
if ($len < strlen ( $p2 )) {
$p2 = substr ( $p2, $len );
} else {
$p2 = '';
}
$p1 .= $bytes . $p2;
$this->byteArray = $p1;
$this->position += $len;
$this->init ();
}
public function readBytes($length = -1, $offset = -1) {
$limit = $this->limit;
if ($offset == - 1) {
$offset = $this->position;
}
if ($length == - 1) {
$length = $limit - $offset;
}
if ($length > $limit - $offset) {
return null;
}
return substr ( $this->byteArray, $offset, $length );
}
public function writeBytes($bytes, $offset = 0, $length = 0) {
$len = strlen ( $bytes );
if ($len < 1) {
return;
}
if ($length < 1) {
$length = $len;
}
if ($offset < 1) {
$offset = 0;
}
if ($offset + $length > $len) {
return;
}
$p1 = substr ( $bytes, $offset, $length );
$this->set ( $p1 );
}
public function readBoolean() {
return $this->readByte () != 0;
}
public function writeBoolean($value) {
$this->writeByte ( $value != 0 );
}
public function readByte() {
return ord ( $this->get ( 1 ) );
}
public function readUnsignedByte() {
$data = unpack ( 'C', $this->get ( 1 ) );
return $data [1];
}
public function writeByte($value) {
$data = pack ( 'c', $value );
$this->set ( $data );
}
public function readShort() {
$data = unpack ( $this->bigEndian ? 'n' : 'v', $this->get ( 2 ) );
return $data [1];
}
public function writeShort($value) {
$data = pack ( $this->bigEndian ? 'n' : 'v', $value );
$this->set ( $data );
}
public function readInt() {
$data = unpack ( $this->bigEndian ? 'N' : 'V', $this->get ( 4 ) );
return $data [1];
}
public function writeInt($value) {
$data = pack ( $this->bigEndian ? 'N' : 'V', $value );
$this->set ( $data );
}
public function readFloat() {
$data = unpack ( 'f', $this->get ( 4 ) );
return $data [1];
}
public function writeFloat($value) {
$data = pack ( 'f', $value );
$this->set ( $data );
}
public function readDouble() {
$data = unpack ( 'd', $this->get ( 8 ) );
return $data [1];
}
public function writeDouble($value) {
$data = pack ( 'd', $value );
$this->set ( $data );
}
public function readString() {
$length = $this->readShort ();
$value = $this->get ( $length );
return $value;
}
public function writeString($value) {
$len = strlen ( $value );
$this->writeShort ( $len );
$this->writeStringBytes ( $value );
}
public function writeStringBytes($value) {
$len = strlen ( $value );
$data = pack ( 'a' . $len, $value );
$this->set ( $data );
}
public function readStringBytes($length) {
return $this->get ( $length );
}
public function bytesAvailable() {
return $this->limit - $this->position;
}
public function length() {
return $this->limit;
}
public function __toString() {
return $this->byteArray;
}
public function compress($level = 5) {
$this->byteArray = gzcompress ( $this->byteArray, $level );
$this->init ();
}
public function uncompress($level = 5) {
$this->byteArray = gzuncompress ( $this->byteArray, $level );
$this->init ();
}
}
?>

Return files from specified directory where Filesize is less than 40kb

i want to select file form directory where filezise in less then 100kb. please check my code its not working
<?php
ob_start();
$dir = '/home/couponsc/public_html/testfile';
$ext = '.mp3';
$search = $_GET['s'];
$results = glob("$dir/*$search*$ext");
foreach($results as $item)
{
$sizes= filesize($item);
if($sizes < 100);
{
echo $item;
}
}
?>
if($sizes < 100);
You have a semi-colon after your if-clause -> empty statement.
foreach($results as $item) {
$sizes= filesize($item);
if($sizes < 40*1024) {
echo $item, "\n";
}
}
Or with a bit more spl/lambda fun + recursion:
<?php
$path = 'c:/temp';
$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path),
RecursiveIteratorIterator::LEAVES_ONLY
);
$it = new FooFilterIterator($it, function($e) { return $e->getSize(); }, function($e) { return $e < 40*1024; } );
foreach($it as $f) {
printf("% 6d %s\n", $f->getSize(), $f);
}
class FooFilterIterator extends FilterIterator {
protected $getter;
protected $filter;
public function __construct(Iterator $source, $getter, $filter) {
parent::__construct($source);
$this->getter = $getter;
$this->filter = $filter;
}
public function accept() {
$f = $this->filter;
$g = $this->getter;
return $f( $g($this->current()) );
}
}
there's also the GlobIterator.
The filesize() function returns bytes, and not kilobytes, thus your condition doesn't work.
the correct condition is:
if($sizes < 102400);

Categories