Last active
February 14, 2023 08:41
-
-
Save DigiLive/b061e070acefd062977549f813f27a72 to your computer and use it in GitHub Desktop.
Collection of PHP functions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Sort an array of rows. | |
* | |
* Sort an array of rows by column names. | |
* For each column to sort on, you pass two additional arguments to this function: | |
* 1 string as the columnName and 1 integer as the sorting flag. | |
* | |
* Pass the array, followed by the column names and sort flags: | |
* $sorted = arrayOrderby($dataArray, 'column1', SORT_DESC, 'column2', SORT_ASC); | |
* | |
* @author F. Cools - DigiLive | |
* @todo: Add Example. | |
* | |
* @param array $dataArray DataRows to be sorted. | |
* @return array Sorted data array. | |
*/ | |
function arrayOrderby(array $dataArray) { | |
$arguments = func_get_args(); | |
$dataArray = array_shift($arguments); | |
foreach ($arguments as $argumentKey => $argumentValue) { | |
if (is_string($argumentValue)) { | |
//Value is a string, so it's a columnName | |
$tempArray = []; | |
foreach ($dataArray as $key => $row) { | |
$tempArray[$key] = $row[$argumentValue]; | |
} | |
$arguments[$argumentKey] = $tempArray; | |
} | |
} | |
$arguments[] = &$dataArray; | |
call_user_func_array('array_multisort', $arguments); | |
return array_pop($arguments); | |
} | |
/** | |
* Filter out array elements if the keyName doesn't start with a specific string. | |
* | |
* @param string $filter SubString to search. | |
* @param array $haystack Array to evaluate. | |
* | |
* @return array Filtered array. | |
*/ | |
function filterKeys($filter, array $haystack) { | |
foreach (array_keys($haystack) as $keyName) { | |
if (substr($keyName, 0, strlen($filter)) != $filter) { | |
unset($haystack[$keyName]); | |
} | |
} | |
return $haystack; | |
} | |
/** | |
* Trim off the whitespace from the beginning and the end of each array element's value. | |
* | |
* If the element is a subarray, the values of this subarray are trimmed by calling this | |
* function recursively. | |
* The argument is supposed to be omitted to trim the values of the global POST variable. | |
* However it's possible to trim the values of a any array by passing it as an argument. | |
* | |
* @param array $array Array with values to trim. | |
*/ | |
function trimPOST(array &$array = null) { | |
if (is_null($array)) { | |
$array = &$_POST; | |
} | |
foreach ($array as &$value) { | |
if (!is_array($value)) { | |
$value = trim($value); | |
} else { | |
trimPOST($value); | |
} | |
} | |
} | |
/** | |
* Strip html and php tags from each array element's value. | |
* | |
* If the element is a subarray, the values of this subarray are stripped by calling this | |
* function recursively. | |
* The argument is supposed to be omitted to strip the values of the global POST variable. | |
* However it's possible to strip the values of a any array by passing it as an argument. | |
* | |
* @param array $array Array with values to strip. | |
*/ | |
function stripPOST($array = null) { | |
if (is_null($array)) { | |
$array = &$_POST; | |
} | |
foreach ($array as &$value) { | |
if (is_array($value)) { | |
stripPOST($value); | |
} else { | |
$value = strip_tags($value); | |
} | |
} | |
} | |
/** | |
* Checks existance of keys of an array. | |
* | |
* KeyNames can be wrapped in an array which is passed to the 2nd parameter | |
* or individual keyNames can be passed to the 2nd paramter and up. | |
* | |
* @param array $array Array to check for key existence. | |
* @param array|string $keys,... Array of keyNames or single keyNames. | |
* | |
* @return bool True when all keys exist in the array, False otherwise. | |
*/ | |
function arrayKeysExist(array $array, $keys) { | |
$count = 0; | |
if (!is_array($keys) ) { | |
$keys = func_get_args(); | |
array_shift($keys); | |
} | |
foreach ($keys as $key) { | |
if (array_key_exists($key, $array)) { | |
$count ++; | |
} | |
} | |
return count($keys) === $count; | |
} | |
/** | |
* Export a 2D data array to a csv file. | |
* | |
* Each element of the 2D data array is an array containing the row data. | |
* I.E. $dataArray[rowNumber][array of row data]. | |
* | |
* Using the first element as a header: $dataArray[0] = array('ColTitle1', 'ColTitle2'); | |
* Following elements as data: $dataArray[1] = array('ColData1', 'ColData1'); | |
* | |
* The 2nd parameter specifies the output destionation of the file. | |
* When it's omitted or an empty string, the file is send to the output buffer. | |
* Otherwise a file, specified by the parameters value, on the file system. | |
* | |
* The 3th parameter specifies the separator of the csv fields. | |
* When ommitted, it defaults to a semicolon. | |
* | |
* Note: | |
* The 2nd parameter can't be omitted when specifying a separator. | |
* To send the file to the output buffer, specify the 2nd parameter as an empty string. | |
* | |
* @param array $data 2D data array containing elements of row data. | |
* @param string $toFile Optional: When a fileName is given, the data is written to this file, otherwise | |
* the data is written to the output buffer | |
* @param string $separator Optional: Character used to separate the values in the exported data. Default = ';' | |
* When defining a list separator, param $toFile must be '' when wanting to write to the output | |
* buffer | |
* | |
* @return bool true on succes, false otherwise | |
*/ | |
function arrayToCsv(array $data, $toFile = '', $separator = ';') { | |
if (!is_string($toFile)) { | |
trigger_error('Paramater toFile is not of type string. Data is written to the output buffer!', E_USER_WARNING); | |
} | |
if ($toFile !== '') { | |
//Open filePointer | |
$output = fopen($toFile, 'w'); | |
} else { | |
//Start Output Buffering | |
ob_start(); | |
//Open Output Buffer | |
$output = fopen('php://output', 'w'); | |
} | |
if ($output == false) { | |
//Output file or buffer can't be openened. | |
return false; | |
} | |
//Write records | |
foreach ($data as $record) { | |
if (fputcsv($output, $record, $separator) === false) { | |
echo 'Error writing data to output!'; | |
} | |
} | |
//Close filePointer/Output Buffer | |
if (!fclose($output)) { | |
if ($toFile == '') { | |
$toFile = 'Output Buffer'; | |
} | |
trigger_error("Error closing filepointer to '$toFile'", E_USER_NOTICE); | |
return false; | |
} | |
if ($toFile !== '') { | |
return true; | |
} | |
//Send headers to the browser to initiate download stream | |
header('Pragma: public'); | |
header('Expires: -1'); | |
header('Cache-Control: public, must-revalidate, post-check=0, pre-check=0'); | |
header('Content-Disposition: attachment;filename="' . date(DATE_FORMAT . '_H-i-s') . '.csv"'); | |
header('Content-Type: text/csv'); | |
header('Content-Length: '.ob_get_length()); | |
// Flush (send) the output buffer and turn off output buffering | |
ob_end_flush(); | |
exit; | |
} | |
/** | |
* Get the lowest or highest value of a (multidimensional) array. | |
* | |
* Note: | |
* The order of low to high is defined the same as the order of php's (r)sort function. | |
* | |
* @param array $array Array containing the values to evaluate. | |
* @param boolean $min True to find the lowest value, False to find the highest. | |
* @return mixed Lowest or highest value in array. | |
*/ | |
function arrayMinMax($array, $min = true) { | |
foreach($array as $key => $value) { | |
if (is_array($value)) { | |
$array[$key] = arrayMinMax($value, $min); | |
} | |
} | |
if ($min) { | |
rsort($array); | |
} else { | |
sort($array); | |
} | |
return array_pop($array); | |
} | |
/** | |
* Sum the values of an array, including the values in a sub array. | |
* | |
* @param array $array Array to sum the values for. | |
* @return number Sum of all (sub)array values. | |
*/ | |
function sumRecursiveArrayValues(array $array) { | |
$total = 0; | |
foreach ($array as $value) { | |
if (is_array($value)) { | |
$total += sumRecursiveArrayValues($value); | |
} else { | |
$total += $value; | |
} | |
} | |
return $total; | |
} | |
/** | |
* Searches the array for a given value and returns the first corresponding key if successful. | |
* | |
* Notes: | |
* If needle is a string, the comparison is done in a case-sensitive manner. | |
* | |
* If the third parameter strict is set to true then the array_search() function will search for identical elements | |
* in the haystack. This means it will also perform a strict type comparison of the needle in the haystack, and | |
* objects must be the same instance. | |
* | |
* @param mixed $needle The searched value. | |
* @param array $haystack The array | |
* @param bool $strict If set to true, the function will search for identical elements. | |
* | |
* @return int|string|false The key of haystack where needle is found, false otherwise. | |
*/ | |
public static function arraySearchRecursive($needle, array $haystack, bool $strict = false) | |
{ | |
foreach ($haystack as $key => $value) { | |
$matchingValue = $strict ? $value === $needle : $value == $needle; | |
if ($matchingValue) { | |
return $key; | |
} | |
if (is_array($value) && self::arraySearchRecursive($needle, $value, $strict) !== false) { | |
return $key; | |
} | |
} | |
return false; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Auto Load Classes. | |
* | |
* Use to load classes when called by the application. | |
* Register this function to spl_autoload_register so you don't have to call this function manually. | |
* | |
* @param string $className Name of class to load. | |
* @throws RuntimeException When the class isn't accessible on the file system. | |
*/ | |
function autoLoader($className) { | |
//Define project nameSpace prefix. | |
$prefix = ''; | |
//Base directory for the nameSpace prefix | |
$baseDir = CLASS_DIR . '/'; | |
//Does the class use the nameSpace prefix? | |
$prefixLength = strlen($prefix); | |
if (strncmp($prefix, $className, $prefixLength) !== 0) { | |
//No, move to the next registered autoloader | |
return; | |
} | |
//Get the relative className. | |
$relativeClassName = substr($className, $prefixLength); | |
/* | |
* Replace the namespace prefix by the base directory. | |
* Replace namespace separators by directory separators in the relative class name. | |
* append with the php file extension. | |
*/ | |
$fileToLoad = $baseDir . str_replace('\\', DIRECTORY_SEPARATOR, $relativeClassName) . '.php'; | |
//Require the file if it exists and can be read. | |
if (is_readable($fileToLoad)) { | |
require_once $fileToLoad; | |
} else { | |
throw new RuntimeException("The AutoLoader tried to require a file which doesn't exist! File: $fileToLoad"); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Detect which field delimiter is used in a separated value file. | |
* | |
* The file is checked for the following delimiters: , tab ; | and : | |
* | |
* The 1st paramter defines the path to the file. | |
* | |
* The 2nd parameter defines how many lines to evaluate. | |
* To evaluate the complete file, make sure this number is at least as high as the number of rows in the file. | |
* When omitted, it defaults to 2. | |
* | |
* @param string $filePath Path to file to be analysed. | |
* @param number $checkLines Number of lines in file to analyse. | |
* @return string|boolean Character which is most likely used as a field delimiter or false on error. | |
*/ | |
function getFieldDelimiter($filePath, $checkLines = 2){ | |
try { | |
$filePath = new SplFileObject($filePath, 'r'); | |
} catch (RuntimeException $e) { | |
return false; | |
} | |
$delimiters = array(',', '\t', ';', '|', ':'); | |
$results = array(); | |
$i = 0; | |
while($filePath->valid() && $i <= $checkLines){ | |
$line = $filePath->fgets(); | |
foreach ($delimiters as $delimiter){ | |
$regExp = '/['.$delimiter.']/'; | |
$fields = preg_split($regExp, $line); | |
if(count($fields) > 1){ | |
if(!empty($results[$delimiter])){ | |
$results[$delimiter]++; | |
} else { | |
$results[$delimiter] = 1; | |
} | |
} | |
} | |
$i++; | |
} | |
$results = array_keys($results, max($results)); | |
if (empty($results)) { | |
return false; | |
} else { | |
return $results[0]; | |
} | |
} | |
/** | |
* Detect which line terminators are used in a file. | |
* | |
* Note: Only the end of the first line is analysed for line terminators. | |
* | |
* @param string $filePath Path to file to be analysed. | |
* @return string|boolean Detected line terminators or false on error. | |
*/ | |
function getLineTerminator($filePath) { | |
$autoDetect = ini_set('auto_detect_line_endings', true); | |
if (($handle = @fopen($filePath, 'r')) !== false) { | |
$line = fgets($handle); | |
fclose($handle); | |
$returnValue = preg_replace('/(*ANYCRLF)./', '', $line); | |
} else { | |
$returnValue = false; | |
} | |
ini_set('auto_detect_line_endings', $autoDetect); | |
return $returnValue; | |
} | |
/** | |
* Copy the contents of a folder to a new folder. | |
* | |
* SubFolders of the source folder will be copied as well. | |
* If the destination folder doesn't exist, it will be created. | |
* | |
* Warning: | |
* This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. | |
* Please read the section on Booleans for more information. Use the === operator for testing the return value of this | |
* function. | |
* | |
* @param string $source Name of the source folder | |
* @param string $destination Name of the new folder | |
* | |
* @return bool|integer True on success, False on error. 0 when source directory doesn't exist. | |
*/ | |
function copyFolder($source, $destination) { | |
$success = true; | |
$sourceFolder = @opendir($source); | |
if ($sourceFolder === false) { | |
return 0; | |
} | |
if (@mkdir($destination, 0777, true) === false) { | |
return false; | |
} | |
while (false !== ($file = readdir($sourceFolder))) { | |
if ($file === false) { | |
$success = false; | |
break; | |
} | |
if (($file != '.') && ($file != '..')) { | |
if (is_dir($source.'/'.$file)) { | |
copyFolder($source.'/'.$file, $destination.'/'.$file); | |
} else { | |
$success = copy($source.'/'.$file, $destination.'/'.$file); | |
} | |
} | |
} | |
closedir($sourceFolder); | |
return $success; | |
} | |
/** | |
* Create a zip archive file. | |
* | |
* The parameter should have an array as argument in the following format: | |
* array('fileName' => array(files of item)) | |
* | |
* @param array $files FileName and filePaths. | |
* @return boolean False When the zip file couldn't be created or read afterwards. | |
*/ | |
function createZip(array $files) | |
{ | |
//Create a temporary zip file | |
$tempName = tempnam('tmp', ''); | |
$zip = new ZipArchive(); | |
$zip->open($tempName); | |
//Add files to the archive | |
foreach ($files as $itemName => $file) { | |
//Sanitize the name to match valid fileName format | |
$invalidChars = array(' ', '.', '/', ''); | |
$itemName = str_replace($invalidChars, '_', $itemName); | |
$matches = []; | |
preg_match_all('/[^0-9^A-Z^a-z^_^.]/', $itemName, $matches); | |
foreach ($matches[0] as $value) { | |
$itemName = str_replace($value, '', $itemName); | |
} | |
$fileCount = count($file); | |
$i = 1; | |
if ($itemName == '') { | |
$itemName = $i; | |
} | |
foreach ($file as $fileName) { | |
$zip->addFile($fileName, $itemName.'_'.$i.'of'.$fileCount.'.'.pathinfo($fileName, PATHINFO_EXTENSION)); | |
++$i; | |
} | |
//Close and reopen the zipfile to avoid passing the upper limit of simultaneously open files. | |
if ($i % 128 == 0) { | |
$zip->close(); | |
$zip->open($tempName); | |
} | |
} | |
$zip->close(); | |
//Sent the zip file to the output buffer | |
if (!is_file($tempName) || !is_readable($tempName)) { | |
return false; | |
} else { | |
header($_SERVER['SERVER_PROTOCOL'].' 200 OK'); | |
header('Content-Type: application/zip'); | |
header('Content-Transfer-Encoding: Binary'); | |
header('Content-Length: '.filesize($tempName)); | |
header('Content-Disposition: attachment; filename=export.zip'); | |
readfile($tempName); | |
exit; | |
} | |
unlink($tempName); | |
} | |
/** | |
* Recursively delete a folder. | |
* The folder and its contents will be deleted. | |
* | |
* @param string $dirName Path to the folder. | |
* @return boolean True on success, False otherwise. | |
*/ | |
function rRmDir($dirName) { | |
if (is_dir($dirName)) { | |
$objects = scandir($dirName); | |
foreach ($objects as $object) { | |
if ($object != "." && $object != "..") { | |
if (filetype($dirName . '/' . $object) == 'dir') { | |
rRmDir($dirName . '/' . $object); | |
} else { | |
unlink($dirName . '/' . $object); | |
} | |
} | |
} | |
reset($objects); | |
return rmdir($dirName); | |
} | |
return true; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Convert a integer number to its ordinal word presentation. | |
* | |
* When the argument is not a integer, this value is returned unchanged. | |
* | |
* @author F. Cools - DigiLive | |
* | |
* @param integer $integer Number to convert to ordinal word presentation | |
* | |
* @return string|mixed Ordinal word presentation the integer or original value. | |
*/ | |
function IntToOrdinalWord($integer) { | |
if (!is_int($integer)) { | |
return $integer; | |
} | |
$firstWord = [ | |
'eth', | |
'First', | |
'Second', | |
'Third', | |
'Fourth', | |
'Fifth', | |
'Sixth', | |
'Seventh', | |
'Eighth', | |
'Ninth', | |
'Tenth', | |
'Elevents', | |
'Twelfth', | |
'Thirteenth', | |
'Fourteenth', | |
'Fifteenth', | |
'Sixteenth', | |
'Seventeenth', | |
'Eighteenth', | |
'Nineteenth', | |
'Twentieth', | |
]; | |
$secondWord = [ | |
'', | |
'', | |
'Twenty', | |
'Thirthy', | |
'Forty', | |
'Fifty', | |
'Sixty', | |
'Seventy', | |
'Eighty', | |
'Ninety', | |
]; | |
if ($integer <= 20) { | |
return $firstWord[$integer]; | |
} | |
$firstNum = substr($integer, -1, 1); | |
$secondNum = substr($integer, -2, 1); | |
return str_replace('y-eth', 'ieth', $secondWord[$secondNum].'-'.$firstWord[$firstNum]); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Copyright (C) 2018 F. Cools | |
The code in this gist is free software: you can redistribute it and/or modify | |
it under the terms of the GNU General Public License as published by | |
the Free Software Foundation, either version 3 of the License, or | |
(at your option) any later version. | |
The code in this gist is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
You should have received a copy of the GNU General Public License | |
along with this gist. If not, see <https://www.gnu.org/licenses/>. | |
======================================================================================================================== | |
This is a collection of PHP functions which I've used in projects. | |
The code may be based on code from sources like stack overflow or any other (open) source I could find on the internet. | |
Please feel free to use this code. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Truncate a string to a maximum of characters. | |
* | |
* Note: | |
* The amount of returned characters may vary, but do not exceed the maximum value. | |
* This is because the returned string will always end in a complete word. | |
* | |
* @param string $string String to truncate. | |
* @param integer $length Max. number of characters. | |
* @return string Truncated string. | |
*/ | |
function truncateString($string, $length) { | |
//Strip tags to avoid breaking any html | |
$string = strip_tags($string); | |
if (strlen($string) > $length) { | |
$stringCut = substr($string, 0, $length); | |
//Make it end in a word | |
$string = substr($stringCut, 0, strrpos($stringCut, ' ')).'…'; | |
} | |
return $string; | |
} | |
/** | |
* Convert a camel-cased string to a snake-cased string. | |
* | |
* @param string $value Camel-cased string. | |
* | |
* @return string Snake-cased string. | |
*/ | |
public static function camelToSnake(string $value): string | |
{ | |
return strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $value)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment