/ Gists / PHP

Gists - PHP

On gists

Exchange rates solution (AMI)

PHP Libs PHP

ExchangeRatesFetcher.php #

<?php
/**
 * Abstraktni trida pro stahovani kurzovnich listku ze stranek bank
 *
 * @date 25-02-2008
 * @version 1.0
 *
 */
abstract class ExchangeRatesFetcher
{
	/**
	 * URL, odkud se kurzy stahuji
	 * 
	 * @var string	 	 
	 */
	protected $url;
	
	/**
	 * kod banky 
	 * 
	 * @var string	 	 
	 */
	protected $bank_code;

	/**
	 * seznam kodu men, ktere chceme stahovat
	 * 
	 * @var array
	 */	 	 	 	
	protected $important_currencies = array('CAD', 'DKK', 'EUR', 'GBP', 'HUF', 'CHF', 'JPY', 'NOK', 'PLN', 'SEK', 'SKK', 'USD', 'RON', 'RUB', 'AUD');
	
	/**
	 * pole stazenych hodnot kurzu
	 * 
	 * @var array	 	 
	 */
	protected $exchange_rates = array();
	
	/**
	 * konstruktor - nastaveni vychozich hodnot
	 * 
	 * @param  string  URL, odkud se kurzy stahuji
	 */
	public function __construct($url)
	{
		$this->url = $url;
	}
	
	/**
	 * funkce vraci pole stazenych kurzu (vhodne napr. pro testovaci vypisy)
	 * 
	 * @return array/false pokud nejsou stazene kurzy vraci false, jinak vraci pole stazenych kurzu 
	 */	 	
	public function getExchangeRates()
	{
		if (is_array($this->exchange_rates)) {
			return $this->exchange_rates;
		}
		else {
			return false;
		}
	}

	/**
	 * funkce vraci kod banky
	 * 
	 * @return string 
	 */	 	
	public function getBankCode()
	{
		return $this->bank_code;
	}
	
	/**
	 * Funkce pro stahnuti kurzovniho listku
	 * 	 	
	 * Funkce stahne kurzovni listek a ulozi ho do interni promenne $exchange_rates
	 */	 	  	 	
	abstract public function fetch();
}

On gists

ICal Event Parser

PHP

ICallParser.php #

<?php

/*
FORK from https://gist.github.com/edewaal97/344ec108931ac4c9e8ca7874b2db83cb
*/


class iCal
{
	/**
	 * @var string
	 */
	public $calendarIdent;

	/**
	 * @var string
	 */
	public $title;

	/**
	 * @var string
	 */
	public $description;

	/**
	 * @var array
	 */
	public $events = array();

	/**
	 * @var array
	 */
	protected $_eventsByDate;


	public function __construct($content = null, $calendarIdent = null)
	{

		$this->calendarIdent = $calendarIdent;
		if ($content) {
			$isUrl = strpos($content, 'http') === 0 && filter_var($content, FILTER_VALIDATE_URL);
			$isFile = strpos($content, "\n") === false && file_exists($content);
			if ($isUrl || $isFile) {
				$content = file_get_contents($content);
			}
			$this->parse($content);
		}

		
	}


	public function title()
	{
		return $this->summary;
	}

	public function description()
	{
		return $this->description;
	}

	public function events()
	{
		return $this->events;
	}

	public function eventsByDate()
	{
		if (! $this->_eventsByDate) {
			$this->_eventsByDate = array();
			$tmpEventsByDate = array();

			foreach ($this->events() as $event) {
				foreach ($event->occurrences() as $occurrence) {
					$date = date('Y-m-d', $occurrence);
					$newevent = clone $event;
					$newevent->fixOccurringDate($occurrence);
					// generate key for sorting
					$key = strtotime($newevent->dateStart);
					while(isset($tmpEventsByDate[$date][$key])) $key++;
					$tmpEventsByDate[$date][$key] = $newevent;
				}
			}

			// sort array
			ksort($tmpEventsByDate);
			foreach ($tmpEventsByDate as $date => $value) {
				ksort($value);
				$this->_eventsByDate[$date] = $value;
			}

			// prevent duplicates for edited dates in recurring events
			foreach ($this->_eventsByDate as $dateKey => $date) {
				foreach ($date as $event) {
					if(!empty($event->recurrenceId)) {
						$uid = $event->uid;

						foreach ($date as $eventKey => $eventValue) {
							if($eventValue->uid == $uid && (empty($eventValue->recurrenceId))) {
								unset($this->_eventsByDate[$dateKey][$eventKey]);
							}
						}

					}
				}
			}
		}

		return $this->_eventsByDate;
	}

	public function eventsByDateBetween($start, $end, int $limit=NULL)
	{
		if ((string) (int) $start !== (string) $start) {
			$start = strtotime($start);
		}
		$start = date('Y-m-d', $start);

		if ((string) (int) $end !== (string) $end) {
			$end = strtotime($end);
		}
		$end = date('Y-m-d', $end);

		$return = array();
		foreach ($this->eventsByDate() as $date => $events) {
			if ($start <= $date && $date < $end) {
				if(empty($limit) || count($return) <= $limit) {
					$return[$date] = $events;
				}
			}
			if(!empty($limit) && count($return) >= $limit){
				break;
			}
		}

		return $return;
	}

	public function eventsByDateSince($start, int $limit=NULL)
	{
		if ((string) (int) $start !== (string) $start) {
			$start = strtotime($start);
		}
		$start = date('Y-m-d', $start);

		$return = array();
		foreach ($this->eventsByDate() as $date => $events) {
			if ($start <= $date) {
				if(empty($limit) || count($return) <= $limit) {
					$return[$date] = $events;
				}
			}
			if(!empty($limit) && count($return) >= $limit){
				break;
			}
		}

		return $return;
	}

	public function eventsByDateUntil($end, int $limit=NULL)
	{
		if ((string) (int) $end !== (string) $end) {
			$end = strtotime($end);
		}

		$start = date('Y-m-d');
		$end = date('Y-m-d', $end);
		$return = array();
		foreach ($this->eventsByDate() as $date => $events) {
			if ($start <= $date && $end >= $date) {
				if(empty($limit) || count($return) <= $limit) {
					$return[$date] = $events;
				}
			}
			if(!empty($limit) && count($return) >= $limit){
				break;
			}
		}
		return $return;
	}

	public function parse($content)
	{
		$content = str_replace("\r\n ", '', $content);

		// Title
		preg_match('`^X-WR-CALNAME:(.*)$`m', $content, $m);
		$this->title = $m ? trim($m[1]) : null;

		// Description
		preg_match('`^X-WR-CALDESC:(.*)$`m', $content, $m);
		$this->description = $m ? trim($m[1]) : null;

		// Events
		preg_match_all('`BEGIN:VEVENT(.+)END:VEVENT`Us', $content, $m);
		foreach ($m[0] as $c) {
			$this->events[] = new iCalEvent($c, $this->calendarIdent);
		}

		return $this;
	}
}



<?php

namespace App\ServiceModule\Model;


class iCalEvent
{

	/**
	 * @var string
	 */
	public $calendarIdent;

	/**
	 * @var string
	 */
	public $uid;

	/**
	 * @var string
	 */
	public $summary;

	/**
	 * @var string
	 */
	public $description;

	/**
	 * @var string
	 */
	public $dateStart;

	/**
	 * @var string
	 */
	public $dateEnd;

	/**
	 * @var string
	 */
	public $recurrenceId;

	/**
	 * @var array
	 */
	public $exdate = array();

	/**
	 * @var \stdClass
	 */
	public $recurrence;

	/**
	 * @var string
	 */
	public $location;

	/**
	 * @var string
	 */
	public $status;

	/**
	 * @var string
	 */
	public $created;

	/**
	 * @var string
	 */
	public $updated;

	/**
	 * @var integer
	 */
	protected $_timeStart;

	/**
	 * @var integer
	 */
	protected $_timeEnd;

	/**
	 * @var integer
	 */
	protected $_recurrenceId;

	/**
	 * @var array
	 */
	protected $_occurrences;


	public function __construct($content = null, $calendarIdent = null)
	{
		if ($content) {
			$this->parse($content);
		}

		$this->calendarIdent = $calendarIdent;
	}


	public function summary()
	{
		return $this->summary;
	}

	public function title()
	{
		return $this->summary;
	}

	public function getEventUrl()
	{
		$eid = explode('@', $this->uid);
		$eid = base64_encode($eid[0] . ' ' . $this->calendarIdent);
		$eid = str_replace('=', '', $eid);

		return $eid;
	}

	public function getEventFullUrl()
	{
		return 'https://www.google.com/calendar/event?eid=' . $this->getEventUrl();
	}

	public function description()
	{
		return $this->description;
	}

	public function occurrences()
	{
		if (empty($this->_occurrences)) {
			$this->_occurrences = $this->_calculateOccurrences();
		}
		return $this->_occurrences;
	}

	public function duration()
	{
		// if ($this->_timeEnd) {
			return $this->_timeEnd - $this->_timeStart;
		// }
	}

	public function parse($content)
	{
		$content = str_replace("\r\n ", '', $content);

		// UID
		if (preg_match('`^UID:(.*)$`m', $content, $m))
			$this->uid = trim($m[1]);

		// Summary
		if (preg_match('`^SUMMARY:(.*)$`m', $content, $m))
			$this->summary = trim($m[1]);

		// Description
		if (preg_match('`^DESCRIPTION:(.*)$`m', $content, $m))
			$this->description = trim($m[1]);

		// Date start
		if (preg_match('`^DTSTART(?:;.+)?:([0-9]+(T[0-9]+Z?)?)`m', $content, $m)) {
			$this->_timeStart = strtotime($m[1]);
			$this->dateStart = date('Y-m-d H:i:s', $this->_timeStart);
		}

		// Date end
		if (preg_match('`^DTEND(?:;.+)?:([0-9]+(T[0-9]+Z?)?)`m', $content, $m)) {
			$this->_timeEnd = strtotime($m[1]);
			$this->dateEnd = date('Y-m-d H:i:s', $this->_timeEnd);
		}

		// Recurrence-Id
		if (preg_match('`^RECURRENCE-ID(?:;.+)?:([0-9]+(T[0-9]+Z?)?)`m', $content, $m)) {
			$this->_recurrenceId = strtotime($m[1]);
			$this->recurrenceId = date('Y-m-d H:i:s', $this->_recurrenceId);
		}

		// Exdate
		if (preg_match_all('`^EXDATE(;.+)?:([0-9]+(T[0-9]+Z?)?)`m', $content, $m)) {
			foreach ($m[2] as $dates) {
				$dates = explode(',', $dates);
				foreach ($dates as $d) {
					$this->exdate[] = date('Y-m-d', strtotime($d));
				}
			}
		}

		// Recurrence
		if (preg_match('`^RRULE:(.*)`m', $content, $m)) {
			$rules = (object) array();
			$rule = trim($m[1]);

			$rule = explode(';', $rule);
			foreach ($rule as $r) {
				list($key, $value) = explode('=', $r);
				$rules->{ strtolower($key) } = $value;
			}

			if (isset($rules->until)) {
				$rules->until = date('Y-m-d H:i:s', strtotime($rules->until));
			}
			if (isset($rules->count)) {
				$rules->count = intval($rules->count);
			}
			if (isset($rules->interval)) {
				$rules->interval = intval($rules->interval);
			}
			if (isset($rules->byday)) {
				$rules->byday = explode(',', $rules->byday);
			}

			// Avoid infinite recurrences
			if (! isset($rules->until) && ! isset($rules->count)) {
				$rules->count = 500;
			}

			$this->recurrence = $rules;
		}


		// Location
		if (preg_match('`^LOCATION:(.*)$`m', $content, $m))
			$this->location = trim($m[1]);

		// Status
		if (preg_match('`^STATUS:(.*)$`m', $content, $m))
			$this->status = trim($m[1]);


		// Created
		if (preg_match('`^CREATED:(.*)`m', $content, $m))
			$this->created = date('Y-m-d H:i:s', strtotime(trim($m[1])));

		// Updated
		if (preg_match('`^LAST-MODIFIED:(.*)`m', $content, $m))
			$this->updated = date('Y-m-d H:i:s', strtotime(trim($m[1])));

		return $this;
	}

	public function isRecurrent()
	{
		return ! empty($this->recurrence);
	}

	public function fixOccurringDate($timestamp)
	{
		if($timestamp != $this->_timeStart) {
			// calculate correct start & end date if not a repeating event
			$duration = $this->duration();

			// get date from occurrences
			$timestampCalc = new \DateTime();
			$timestampCalc->setTimestamp($timestamp);

			// make new startdate and start timestamp
			$startCalc = new \DateTime();
			$startCalc->setTimestamp($this->_timeStart);
			$startCalc->setDate($timestampCalc->format('Y'), $timestampCalc->format('m'), $timestampCalc->format('d'));
			$this->_timeStart = $startCalc->getTimestamp();
			$this->dateStart = date('Y-m-d H:i:s', $this->_timeStart);

			// calculate end date and time with duration of original event.
			$this->_timeEnd += - $this->_timeStart + $duration;
			$this->dateEnd = date('Y-m-d H:i:s', $this->_timeEnd);
		}
	}

	protected function _isExdate($date)
	{
		if ((string) (int) $date != $date) {
			$date = strtotime($date);
		}
		$date = date('Y-m-d', $date);

		return in_array($date, $this->exdate);
	}

	protected function _calculateOccurrences()
	{
		$occurrences = array($this->_timeStart);

		if ($this->isRecurrent())
		{
			$freq = $this->recurrence->freq;
			$count = isset($this->recurrence->count) ? $this->recurrence->count : null;
			$until = isset($this->recurrence->until) ? strtotime($this->recurrence->until) : null;

			$callbacks = array(
				'YEARLY' => '_nextYearlyOccurrence',
				'MONTHLY' => '_nextMonthlyOccurrence',
				'WEEKLY' => '_nextWeeklyOccurrence',
				'DAILY' => '_nextDailyOccurrence'
			);
			$callback = $callbacks[$freq];

			$offset = $this->_timeStart;
			$continue = $until ? ($offset < $until) : ($count > 1);
			while ($continue) {
				if(isset($occurrence)) {
					if (! $this->_isExdate($occurrence)) {
						$occurrences[] = $occurrence;
						$count--;
					}

				}
				$occurrence = $this->{$callback}($offset);

				$offset = $occurrence;

				$continue = $until ? ($offset < $until) : ($count > 1);
			}
		}

		if ($this->_isExdate($occurrences[0])) {
			unset($occurrences[0]);
			$occurrences = array_values($occurrences);
		}

		return $occurrences;
	}

	protected function _nextYearlyOccurrence($offset)
	{
		$interval = isset($this->recurrence->interval)
			? $this->recurrence->interval
			: 1;

		return strtotime("+{$interval} year", $offset);
	}

	protected function _nextMonthlyOccurrence($offset)
	{
		$dayname = array(
			'MO' => 'monday',
			'TU' => 'tuesday',
			'WE' => 'wednesday',
			'TH' => 'thursday',
			'FR' => 'friday',
			'SA' => 'saturday',
			'SU' => 'sunday'
		);

		$interval = isset($this->recurrence->interval)
			? $this->recurrence->interval
			: 1;

		// INTERVAL IS BY (COUNT)DAYNAME
		if(isset($this->recurrence->byday)){
			$dates = array();
			foreach ($this->recurrence->byday as $pattern) {
				$offsetDateTime = new \DateTime();
				$offsetDateTime->setTimestamp((int) $offset);

				preg_match('`([-]?\d+)?(MO|TU|WE|TH|FR|SA|SU)`m', $pattern, $m);
				$recurrenceOffset = (isset($m[1])) ? (int) $m[1] : 1;
				$recurrenceDay = strtr($m[2], $dayname);

				$forDateTime = clone $offsetDateTime;

				for (
					$month = (int) $offsetDateTime->format('Ym');
					$month <= date('Ym', strtotime('+' . $interval*12 . ' months'));
					$month = (int) $forDateTime->modify('+'.$interval.' months')->format('Ym')
				) {
					$yearMonth = $forDateTime->format('Y-m');
					$firstDay = new \DateTime('first '. $recurrenceDay . ' of ' . $yearMonth);
					$lastDay = new \DateTime('last '. $recurrenceDay . ' of ' . $yearMonth);

					$newDate = $firstDay;

					$daysInMonth = array();
					while ($newDate->getTimestamp() <= $lastDay->getTimestamp()) {
						$daysInMonth[] = $newDate->getTimestamp();
						$newDate->modify('next '. $recurrenceDay);
					}

					if($recurrenceOffset < 0) {
						$dates[] = $daysInMonth[count($daysInMonth) + $recurrenceOffset];
					} else {
						$dates[] = $daysInMonth[$recurrenceOffset - 1];
					}
				}
			}
			sort($dates);

			foreach ($dates as $date) {
				if ($date > $offset) {
					return $date;
				}
			}
		}

		// INTERVAL IS BY DAYNUMBER OF MONTH
		$bymonthday = isset($this->recurrence->bymonthday)
			? explode(',', $this->recurrence->bymonthday)
			: array(date('d', $offset));

		$start = strtotime(date('Y-m-01 H:i:s', $offset));

		$dates = array();
		foreach ($bymonthday as $day) {
			// this month
			$dates[] = strtotime(($day-1) . ' day', $start);

			// next 'interval' month
			$tmp = strtotime("+{$interval} month", $start);
			$time = strtotime(($day-1) . ' day', $tmp);
			if ((string) (int) date('d', $time) == (int) $day) {
				$dates[] = $time;
			}

			// 2x 'interval' month
			$interval *= 2;
			$tmp = strtotime("+{$interval} month", $start);
			$time = strtotime(($day-1) . ' day', $tmp);
			if ((string) (int) date('d', $time) === (int) $day) {
				$dates[] = $time;
			}
		}
		sort($dates);

		foreach ($dates as $date) {
			if ($date > $offset) {
				return $date;
			}
		}
	}

	protected function _nextWeeklyOccurrence($offset)
	{
		$interval = isset($this->recurrence->interval)
			? $this->recurrence->interval
			: 1;

		$byday = isset($this->recurrence->byday)
			? $this->recurrence->byday
			: array( substr(strtoupper(date('D', $offset)), 0, 2) );

		$start = date('l', $offset) !== 'Monday'
			? strtotime('last monday', $offset)
			: $offset;

		$daysname = array(
			'MO' => 'monday',
			'TU' => 'tuesday',
			'WE' => 'wednesday',
			'TH' => 'thursday',
			'FR' => 'friday',
			'SA' => 'saturday',
			'SU' => 'sunday',
		);

		$dates = array();
		foreach ($byday as $day) {
			$dayname = $daysname[$day];

			// this week
			$dates[] = strtotime($dayname, $start);

			// next 'interval' week
			$tmp = strtotime("+{$interval} week", $start);
			$time = strtotime($dayname, $tmp);
			$dates[] = $time;
		}
		sort($dates);

		foreach ($dates as $date) {
			if ($date > $offset) {
				return $date;
			}
		}
	}

	protected function _nextDailyOccurrence($offset)
	{
		$interval = isset($this->recurrence->interval)
			? $this->recurrence->interval
			: 1;

		return strtotime("+{$interval} day", $offset);
	}
}

On gists

PHP Diacritics regexp

PHP

dia.php #

<?php

if (preg_match('/[áčďéěíňóřšűőťúůýž]+/iu', $string)) {
    // obsahuje diakritiku
}

On gists

Magic Method: __invoke

PHP

wakeup.php #

<?php


class User {

    protected $name;  
    protected $timeline = array();

    public function __construct($name)  
    {  
        $this->name = $name;  
    }

    public function addTweet(Tweet $tweet)  
    {  
        $this->timeline[] = $tweet;  
    }

}

class Tweet {

    protected $id;  
    protected $text;  
    protected $read;

    public function __construct($id, $text)  
    {  
        $this->id = $id;  
        $this->text = $text;  
        $this->read = false;  
    }

    public function __invoke($user)  
    {  
        $user->addTweet($this);  
        return $user;  
    }

}

$users = array(new User('Ev'), new User('Jack'), new User('Biz'));  
$tweet = new Tweet(123, 'Hello world');  
$users = array_map($tweet, $users);

var_dump($users);

On gists

PHP DOM - saveHtml (solution without entities and html,body tags)

PHP PHP-PHPDOM

dom.php #

<?php
 
$string = '<div>ěščřžýáíé</div><p>testik</p> <p>testik2</p>';
 
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->loadHTML('<body>'.mb_convert_encoding($string, 'HTML-ENTITIES', 'UTF-8').'</body>');
 
// změny na $dom
 
echo substr($dom->saveHTML($dom->documentElement), 12, -14);

On gists

PHP CLI colors & getopts commands

PHP CLI

cli.php #

<?php

// https://www.supercoders.in/2019/07/php-command-line-php-parsing-program_16.html
// https://misc.flogisoft.com/bash/tip_colors_and_formatting
// https://joshtronic.com/2013/09/02/how-to-use-colors-in-command-line-output/

$longopts  = array(
    "required:",     // Required value
    "optional::",    // Optional value
    "option",        // No value
    "opt",           // No value
);

$options = getopt("", $longopts);

echo "\e[0;34;41mMerry Christmas!\e[0m\n";
echo "kunda";
echo "\033[31m some colored text \033[0m some white text \n";
echo  "Normal \e[5mBlink \n";
echo "Normal \e[1mBold \n";
echo "Default \e[33mYellow \n";


On gists

Microtime - rychlost měření php kódu

PHP

mereni.php #

<?php


function starttime() {
$r = explode( ' ', microtime() );
$r = $r[1] + $r[0];
return $r;
}

function endtime($starttime) {
$r = explode( ' ', microtime() );
$r = $r[1] + $r[0];
$r = round($r - $starttime,4);
return '<strong>Execution Time</strong>: '.$r.' seconds<br />';
}



$start = starttime();

$list = [1,2,3,4,5];

for ($i=0 ; $i< 1e5; $i++) {
    
	if (count($list))
	{
	}
}

echo endtime($start);



$start = starttime();

$list = [1,2,3,4,5];

for ($i=0 ; $i< 1e6; $i++) {
    
	if (!isset($x))
	{
		$x = [];
	}
}

echo endtime($start);

On gists

Distance between 2 points

PHP

distance.php #

<?php


echo get_distance(50.0598058, 14.3255396, 51.0769658, 13.6325016, 'Km');


function get_distance($latitude1, $longitude1, $latitude2, $longitude2, $unit = 'Mi') { 
    $theta = $longitude1 - $longitude2; 
    $distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) + 
                (cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * 
                cos(deg2rad($theta))); 
    $distance = acos($distance); 
    $distance = rad2deg($distance); 
    $distance = $distance * 60 * 1.1515; 
    switch($unit) { 
        case 'Mi': 
            break; 
        case 'Km' : 
            $distance = $distance * 1.609344; 
    } 
    return (round($distance,2)); 
}

On gists

Remove accents

PHP

remove.php #

<?php

function removeAccents($str)
{
    static $map = [
        // single letters
        'à' => 'a',
        'á' => 'a',
        'â' => 'a',
        'ã' => 'a',
        'ä' => 'a',
        'ą' => 'a',
        'å' => 'a',
        'ā' => 'a',
        'ă' => 'a',
        'ǎ' => 'a',
        'ǻ' => 'a',
        'À' => 'A',
        'Á' => 'A',
        'Â' => 'A',
        'Ã' => 'A',
        'Ä' => 'A',
        'Ą' => 'A',
        'Å' => 'A',
        'Ā' => 'A',
        'Ă' => 'A',
        'Ǎ' => 'A',
        'Ǻ' => 'A',


        'ç' => 'c',
        'ć' => 'c',
        'ĉ' => 'c',
        'ċ' => 'c',
        'č' => 'c',
        'Ç' => 'C',
        'Ć' => 'C',
        'Ĉ' => 'C',
        'Ċ' => 'C',
        'Č' => 'C',

        'ď' => 'd',
        'đ' => 'd',
        'Ð' => 'D',
        'Ď' => 'D',
        'Đ' => 'D',


        'è' => 'e',
        'é' => 'e',
        'ê' => 'e',
        'ë' => 'e',
        'ę' => 'e',
        'ē' => 'e',
        'ĕ' => 'e',
        'ė' => 'e',
        'ě' => 'e',
        'È' => 'E',
        'É' => 'E',
        'Ê' => 'E',
        'Ë' => 'E',
        'Ę' => 'E',
        'Ē' => 'E',
        'Ĕ' => 'E',
        'Ė' => 'E',
        'Ě' => 'E',

        'ƒ' => 'f',


        'ĝ' => 'g',
        'ğ' => 'g',
        'ġ' => 'g',
        'ģ' => 'g',
        'Ĝ' => 'G',
        'Ğ' => 'G',
        'Ġ' => 'G',
        'Ģ' => 'G',


        'ĥ' => 'h',
        'ħ' => 'h',
        'Ĥ' => 'H',
        'Ħ' => 'H',

        'ì' => 'i',
        'í' => 'i',
        'î' => 'i',
        'ï' => 'i',
        'ĩ' => 'i',
        'ī' => 'i',
        'ĭ' => 'i',
        'į' => 'i',
        'ſ' => 'i',
        'ǐ' => 'i',
        'Ì' => 'I',
        'Í' => 'I',
        'Î' => 'I',
        'Ï' => 'I',
        'Ĩ' => 'I',
        'Ī' => 'I',
        'Ĭ' => 'I',
        'Į' => 'I',
        'İ' => 'I',
        'Ǐ' => 'I',

        'ĵ' => 'j',
        'Ĵ' => 'J',

        'ķ' => 'k',
        'Ķ' => 'K',


        'ł' => 'l',
        'ĺ' => 'l',
        'ļ' => 'l',
        'ľ' => 'l',
        'ŀ' => 'l',
        'Ł' => 'L',
        'Ĺ' => 'L',
        'Ļ' => 'L',
        'Ľ' => 'L',
        'Ŀ' => 'L',


        'ñ' => 'n',
        'ń' => 'n',
        'ņ' => 'n',
        'ň' => 'n',
        'ʼn' => 'n',
        'Ñ' => 'N',
        'Ń' => 'N',
        'Ņ' => 'N',
        'Ň' => 'N',

        'ò' => 'o',
        'ó' => 'o',
        'ô' => 'o',
        'õ' => 'o',
        'ö' => 'o',
        'ð' => 'o',
        'ø' => 'o',
        'ō' => 'o',
        'ŏ' => 'o',
        'ő' => 'o',
        'ơ' => 'o',
        'ǒ' => 'o',
        'ǿ' => 'o',
        'Ò' => 'O',
        'Ó' => 'O',
        'Ô' => 'O',
        'Õ' => 'O',
        'Ö' => 'O',
        'Ø' => 'O',
        'Ō' => 'O',
        'Ŏ' => 'O',
        'Ő' => 'O',
        'Ơ' => 'O',
        'Ǒ' => 'O',
        'Ǿ' => 'O',


        'ŕ' => 'r',
        'ŗ' => 'r',
        'ř' => 'r',
        'Ŕ' => 'R',
        'Ŗ' => 'R',
        'Ř' => 'R',


        'ś' => 's',
        'š' => 's',
        'ŝ' => 's',
        'ş' => 's',
        'Ś' => 'S',
        'Š' => 'S',
        'Ŝ' => 'S',
        'Ş' => 'S',

        'ţ' => 't',
        'ť' => 't',
        'ŧ' => 't',
        'Ţ' => 'T',
        'Ť' => 'T',
        'Ŧ' => 'T',


        'ù' => 'u',
        'ú' => 'u',
        'û' => 'u',
        'ü' => 'u',
        'ũ' => 'u',
        'ū' => 'u',
        'ŭ' => 'u',
        'ů' => 'u',
        'ű' => 'u',
        'ų' => 'u',
        'ư' => 'u',
        'ǔ' => 'u',
        'ǖ' => 'u',
        'ǘ' => 'u',
        'ǚ' => 'u',
        'ǜ' => 'u',
        'Ù' => 'U',
        'Ú' => 'U',
        'Û' => 'U',
        'Ü' => 'U',
        'Ũ' => 'U',
        'Ū' => 'U',
        'Ŭ' => 'U',
        'Ů' => 'U',
        'Ű' => 'U',
        'Ų' => 'U',
        'Ư' => 'U',
        'Ǔ' => 'U',
        'Ǖ' => 'U',
        'Ǘ' => 'U',
        'Ǚ' => 'U',
        'Ǜ' => 'U',


        'ŵ' => 'w',
        'Ŵ' => 'W',

        'ý' => 'y',
        'ÿ' => 'y',
        'ŷ' => 'y',
        'Ý' => 'Y',
        'Ÿ' => 'Y',
        'Ŷ' => 'Y',

        'ż' => 'z',
        'ź' => 'z',
        'ž' => 'z',
        'Ż' => 'Z',
        'Ź' => 'Z',
        'Ž' => 'Z',


        // accentuated ligatures
        'Ǽ' => 'A',
        'ǽ' => 'a',
    ];
    return strtr($str, $map);
}

On gists

Iteration and Recursive Iteration Examples Code

PHP

iteration-and-recursive-iteratio #

<?php
/*
* Iteration and Recursive Iteration Examples Code
*
* @link http://stackoverflow.com/questions/12077177/how-does-recursiveiteratoriterator-works-in-php
* @author hakre <http://hakre.wordpress.com>
*/

### To have these examples to work, a directory with subdirectories is needed,
### I named mine "tree":

$path = 'tree';


/**
 * Example 1: DirectoryIterator
 */
$dir = new DirectoryIterator($path);

echo "[$path]\n";
foreach ($dir as $file) {
    echo " ├ $file\n";
}


/**
 * Example 2: IteratorIterator
 */
$files = new IteratorIterator($dir);

echo "[$path]\n";
foreach ($files as $file) {
    echo " ├ $file\n";
}


/**
 * Example 3: RecursiveDirectoryIterator
 */
$dir = new RecursiveDirectoryIterator($path);

echo "[$path]\n";
foreach ($dir as $file) {
    echo " ├ $file\n";
}


/**
 * Example 4: RecursiveIteratorIterator
 */
$files = new RecursiveIteratorIterator($dir);

echo "[$path]\n";
foreach ($files as $file) {
    echo " ├ $file\n";
}


/**
 * Example 5: Meta-Information
 */
echo "[$path]\n";
foreach ($files as $file) {
    $indent = str_repeat('   ', $files->getDepth());
    echo $indent, " ├ $file\n";
}


/**
 * Example 6: Recursion Mode
 */
$dir   = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::SELF_FIRST);

echo "[$path]\n";
foreach ($files as $file) {
    $indent = str_repeat('   ', $files->getDepth());
    echo $indent, " ├ $file\n";
}


/**
 * Appendix: Nicely Formatted Directory Listings (as used in the answer)
 */
$unicodeTreePrefix = function(RecursiveTreeIterator $tree)
{
    $prefixParts = [
        RecursiveTreeIterator::PREFIX_LEFT         => ' ',
        RecursiveTreeIterator::PREFIX_MID_HAS_NEXT => '│ ',
        RecursiveTreeIterator::PREFIX_END_HAS_NEXT => '├ ',
        RecursiveTreeIterator::PREFIX_END_LAST     => '└ '
    ];
    foreach ($prefixParts as $part => $string) {
        $tree->setPrefixPart($part, $string);
    }
};

$dir  = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_FILENAME | RecursiveDirectoryIterator::SKIP_DOTS);
$tree = new RecursiveTreeIterator($dir);
$unicodeTreePrefix($tree);

### non-recursive and recursive listing
foreach ([0, -1] as $level) {
    $tree->setMaxDepth($level);
    echo "[$path]\n";
    foreach ($tree as $filename => $line) {
        echo $tree->getPrefix(), $filename, "\n";
    }
}


/**
 * Appendix: Do It Yourself: Make the `RecursiveTreeIterator` Work Line by Line.
 */
$dir   = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
$lines = new RecursiveTreeIterator($dir);
$unicodeTreePrefix($lines);
echo "[$path]\n", implode("\n", iterator_to_array($lines));

echo "

/// Solution Suggestion ///

";
@include('recursive-directory-iterator-solution.php');

$lines = new RecursiveTreeIterator(
    new DiyRecursiveDecorator($dir)
);
$unicodeTreePrefix($lines);
echo "[$path]\n", implode("\n", iterator_to_array($lines));