Php simple algorithm for autoloader - php

Here's my "simple" algorithm:
if the class is named like 'AaaBbbCccDddEeeFff' loop like this:
include/aaa/bbb/ccc/ddd/eee/fff.php
include/aaa/bbb/ccc/ddd/eee_fff.php
include/aaa/bbb/ccc/ddd_eee_fff.php
include/aaa/bbb/ccc_ddd_eee_fff.php
include/aaa/bbb_ccc_ddd_eee_fff.php
include/aaa_bbb_ccc_ddd_eee_fff.php
if still nothing found, try to look if those files exist:
include/aaa/bbb/ccc/ddd/eee/fff/base.php
include/aaa/bbb/ccc/ddd/eee/base.php
include/aaa/bbb/ccc/ddd/base.php
include/aaa/bbb/ccc/base.php
include/aaa/bbb/base.php
include/aaa/base.php
include/base.php
If still not found then error.
I'm looking for a fast and easy way to convert this:
'AaaBbbCccDddEeeFff'
to this:
include/aaa/bbb/ccc/ddd/eee/fff.php
and then and easy way to remove latest folder (I guess I should look for explode()).
Any idea how to do this? (I'm not asking for the whole code, I'm not lazy).

Since you specifically asked not to have the whole code, here is some code to get you started. This takes the input and divides it into chunks delineated by changes in case. The rest you can work out as an exercise.
<?php
$input = "AaaBbbCccDddEeeFff";
$str_so_far = "";
$last_was_upper = 0;
$chunks = array();
while($next_letter = substr($input,0,1)) {
$is_upper = (strtoupper($next_letter)==$next_letter);
if($str_so_far && $is_upper && !$last_was_upper) {
$chunks[] = $str_so_far;
$str_so_far = "";
}
if($str_so_far && !$is_upper && $last_was_upper) {
$chunks[] = $str_so_far;
$str_so_far = "";
}
$str_so_far .= $next_letter;
$input = substr($input,1);
$last_was_upper = $is_upper;
}
var_dump($chunks);
?>

I think a regular expression would work. Something like preg_match_all('[A-Z][a-z][a-z]'
, $string); might work - that would match a capital letter, followed by a lowercase letter, and another lowercase letter.

As the other answers are regex, here's a non-regex way for completeness:
function transform($str){
$arr = array();
$part = '';
for($i=0; $i<strlen($str); $i++){
$char = substr($str, $i, 1);
if(ctype_upper($char) && $i > 0){
$arr[] = $part;
$part = '';
}
$part .= $char;
}
$arr[] = $part;
return 'include/' . strtolower(implode('/', $arr)) . '.php';
}
echo transform('AaaBbbCccDddEeeFff');
// include/aaa/bbb/ccc/ddd/eee/fff.php
This builds an array of the folders, so you can manipulate it as needed, for example remove a folder by unsetting the desired index, before it gets imploded.

Here is the first part of your algorithm:
AaaBbbCccDddEeeFff -> include/aaa/bbb/ccc/ddd/eee/fff.php
include/aaa/bbb/ccc/ddd/eee_fff.php
include/aaa/bbb/ccc/ddd_eee_fff.php
include/aaa/bbb/ccc_ddd_eee_fff.php
include/aaa/bbb_ccc_ddd_eee_fff.php
include/aaa_bbb_ccc_ddd_eee_fff.php
I think you can do last part independently based on my answer.
<?php
function convertClassToPath($class) {
return strtolower(preg_replace('/([a-z])([A-Z])/', '$1' . DIRECTORY_SEPARATOR . '$2', $class)) . '.php';
}
function autoload($path) {
$base_dir = 'include' . DIRECTORY_SEPARATOR;
$real_path = $base_dir . $path;
var_dump('Checking: ' . $real_path);
if (file_exists($real_path) === true) {
var_dump('Status: Success');
include $real_path;
} else {
var_dump('Status: Fail');
$last_separator_pos = strrpos($path, DIRECTORY_SEPARATOR);
if ($last_separator_pos === false) {
return;
} else {
$path = substr_replace($path, '_', $last_separator_pos, 1);
autoload($path);
}
}
}
$class = 'AaaBbbCccDddEeeFff';
var_dump(autoload(convertClassToPath($class)));

Related

PHP dynamic breadcrumb script creates wrong URL after switching to PHP 8.0

I'm using a PHP script to create a dynamic breadcrumb navigation. I found it several years ago in another forum where it was originally posted in 2006. I updated it by removing some deprecated functions and it worked well so far. It creates the crumbs from the page URL:
$path = $this->_homepath;
$html ='';
$html .= 'Start';
$parts = explode('/', $_SERVER['PHP_SELF']);
$partscount = count($parts);
for($i = 1; $i < ($partscount - 1); $i++) {
$path .= $parts[$i] . '/';
$title = $parts[$i];
if ($this->_usereplacements == true) {
reset($this->_replacements);
foreach($this->_replacements as $search => $replace) {
$title = str_replace($search, $replace, $title);
}
}
if ($this->_replaceunderlines == true) {
$title = str_replace('_', ' ', $title);
}
if ($this->_ucfirst == true) {
$title = ucfirst($title);
}
if ($this->_ucwords == true) {
$title = ucwords($title);
}
$html .= $this->_separator . '' . $title . '';
}
The current page title, i.e. the last element of the bradcrumb, is generated as follows:
$title = '';
if ($title == '') {
$title = $parts[$partscount-1];
if ($this->_usereplacements == true) {
reset($this->_replacements);
foreach($this->_replacements as $search => $replace) {
$title = str_replace($search, $replace, $title);
}
}
if ($this->_removeextension == true) {
$title = substr($title, 0, strrpos($title, '.'));
}
if ($this->_replaceunderlines == true) {
$title = str_replace('_', ' ', $title);
}
if ($this->_ucfirst == true) {
$title = ucfirst($title);
}
if ($this->_ucwords == true) {
$title = ucwords($title);
}
}
$html .= $this->_separator . '<b>' . $title . '</b>';
I only copied relevant parts of the script and spared eg. the function declarations.
After switching from PHP 7.4 to 8.0 I found that the script is messing up a bit. Consider a page with this url: https://www.myhomepage.com/site1/site2/site3
For the crumbs of site1 the script is now generating the URL https://www.myhomepage.com/site1/site2/site1 insted of https://www.myhomepage.com/site1/, whereas for site2 it shows https://www.myhomepage.com/site1/site2/site1/site2 instead of https://www.myhomepage.com/site1/site2/. As you can see, the whole path https://www.myhomepage.com/site1/site2/ is always added as a prefix before the actual path of the crumb.
I haven't found a solution yet despite looking over this thing for two days. I suppose there have been some changes in PHP 8.0 which causes this behaviour, but I haven't found any clues in the incompatibility list (https://www.php.net/manual/de/migration80.php). I printed §path and $title and they look like they should. When echoing $html after each iteration in the for loop it shows already the wrong URLs. That's why I think that probably the for loop is the problem here. Do you have any suggestions?
Any help on this would be very much appreciated.
I finally was able to figure out what causes the strange behaviour of the script. In the declaration of the breadcrumb constructing function there is $this->_homepath = '/';. Later on I assign $path = $this->_homepath;. When I echo $path its empty instead of showing the aforementioned "/". So I directly set $path = '/'; and now everything works again as it should.

How to fix url contains arabic characters

I want to get the url of each file in certain directory
i tried string concatenation (like: domain.folder1.folder2.file.mp3) but some folders and files is with arabic characters that make error when using the url.
example:
this is my code output:
String A :
https://linkimage2url.com/apps/quran full/محمد صديق المنشاوي/تسجيلات الإذاعة المصرية/009 - At-Taubah (The Repentance) سورة التوبة.mp3
this code is not working in some android devices
but the next code works with all devices
String B:
https://linkimage2url.com/apps/quran%20full/%D9%85%D8%AD%D9%85%D8%AF%20%D8%B5%D8%AF%D9%8A%D9%82%20%D8%A7%D9%84%D9%85%D9%86%D8%B4%D8%A7%D9%88%D9%8A/%D8%AA%D8%B3%D8%AC%D9%8A%D9%84%D8%A7%D8%AA%20%D8%A7%D9%84%D8%A5%D8%B0%D8%A7%D8%B9%D8%A9%20%D8%A7%D9%84%D9%85%D8%B5%D8%B1%D9%8A%D8%A9/009%20-%20At-Taubah%20(The%20Repentance)%20%D8%B3%D9%88%D8%B1%D8%A9%20%D8%A7%D9%84%D8%AA%D9%88%D8%A8%D8%A9.mp3
Note: i got String B from internet download manager that converts it automatically when i tried to use string A
my question is:
how to convert String A to String B by php
and is there better way to readdir and get the url of each file
My code is:
if(is_dir($parent)){
if($dh = opendir($parent)){
while(($file = readdir($dh)) != false){
if($file == "." or $file == ".."){
//...
} else { //create object with two fields
sort($file);
$fileName = pathinfo($file)['filename'];
if(is_dir($parent."/".$file)){
$data[] = array('name'=> $fileName, 'subname'=> basename($path), 'url'=> $path."/".$file, "directory"=> true);
} else {
$res = "https://linkimage2url.com".$path."/".$file;
$data[] = array('name'=> $fileName, 'subname'=> basename($path), 'url'=> $res , "directory"=> false);
}
Try this one, I've used once for a legacy project:
function encode_fullurl($url) {
$output = '';
$valid = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~!*\'();:#&=+$,/?#[]%';
$length = strlen($url);
for ($i = 0; $i < $length; $i++) {
$character = $url[$i];
$output .= (strpos($valid, $character) === false ? rawurlencode($character) : $character);
}
return $output;
}
$url ="https://linkimage2url.com/apps/quran full/محمد صديق المنشاوي/تسجيلات الإذاعة المصرية/009 - At-Taubah (The Repentance) سورة التوبة.mp3";
echo encode_fullurl($url);
output:
https://linkimage2url.com/apps/quran%20full/%D9%85%D8%AD%D9%85%D8%AF%20%D8%B5%D8%AF%D9%8A%D9%82%20%D8%A7%D9%84%D9%85%D9%86%D8%B4%D8%A7%D9%88%D9%8A/%D8%AA%D8%B3%D8%AC%D9%8A%D9%84%D8%A7%D8%AA%20%D8%A7%D9%84%D8%A5%D8%B0%D8%A7%D8%B9%D8%A9%20%D8%A7%D9%84%D9%85%D8%B5%D8%B1%D9%8A%D8%A9/009%20-%20At-Taubah%20(The%20Repentance)%20%D8%B3%D9%88%D8%B1%D8%A9%20%D8%A7%D9%84%D8%AA%D9%88%D8%A8%D8%A9.mp3
it is not very performing, but it should do what you need
this code worked for me
thanks every one
$res1 = "https://linkimage2url.com" .$path."/".$file;
$query = flash_encode ($res1);
$url = htmlentities($query);
function flash_encode($string)
{
$string = rawurlencode($string);
$string = str_replace("%2F", "/", $string);
$string = str_replace("%3A", ":", $string);
return $string;
}

PHP issue reading huge data from txt files

I'm running a php script that reads from some pipe-delimited txt files, those files contain around 22,000 records. I'm using PHP file() function to read those files, BTW the files have some inter-relation too, I'm pasting the code here for better understanding
public function getGames()
{
$resource = self::DATAFILES.'Product.txt';
$games = array_slice($this->readFile($resource), 1);
$data = array();
$count = 1;
foreach($games as &$records)
{
$game = new Game();
$attributes = explode($this->delimiter,$records);
$game->api = (int) $attributes[0];
$game->console_id = (string) $attributes[1];
$game->title = (string) $this->getTitle($attributes[2]);
$game->barcode = (string) $attributes[4];
$game->image = $this->getCoverImage($attributes[0]);
$game->releateDate = strtotime($attributes[8]);
$data[] = $game;
//if($count == 100): break; else: $count++; endif;
}
print '<pre>'; print_r($data);
}
public function getTitle($titleID)
{
$resource = self::DATAFILES.'Title.txt';
$titles = array_slice($this->readFile($resource), 1);
foreach($titles as $records)
{
$attributes = explode($this->delimiter,$records);
$pattern = '/^' . preg_quote($attributes[0], '/') . '$/';
if (preg_match($pattern, $titleID))
{
return $attributes[2];
break;
}
}
}
public function getCoverImage($gameID)
{
$resource1 = self::DATAFILES.'ProductImage.txt';
$coverImages = array_slice($this->readFile($resource1), 1);
foreach($coverImages as $img_records)
{
$image_attributes = explode($this->delimiter,$img_records);
$pattern1 = '/^' . preg_quote($image_attributes[0], '/') . '$/';
$pattern2 = '/^' . preg_quote($image_attributes[3], '/') . '$/';
if (preg_match($pattern1, $gameID) && preg_match($pattern2, 'Cover'))
{
return $image_attributes[2];
break;
}
}
So the problem I'm facing here is that - when I run that script it will just go on and on nothing happens i.e never throws any error neither print the returned array, however when I limit's the loop iteration up to 100 it works which means nothing wrong with the code so I thought perhaps, php script execution time making trouble so I changed it to max_execution_time = 0 - but still not getting the results. Any help or suggestion, would love hear that.. :)
BTW I'm using Xampp Apache for my local dev !

Function for each subfolder in PHP

I am new in PHP and can't figure out how to do this:
$link = 'http://www.domainname.com/folder1/folder2/folder3/folder4';
$domain_and_slash = http://www.domainname.com . '/';
$address_without_site_url = str_replace($domain_and_slash, '', $link);
foreach ($folder_adress) {
// function here for example
echo $folder_adress;
}
I can't figure out how to get the $folder_adress.
In the case above I want the function to echo these four:
folder1
folder1/folder2
folder1/folder2/folder3
folder1/folder2/folder3/folder4
The $link will have different amount of subfolders...
This gets you there. Some things you might explore more: explode, parse_url, trim. Taking a look at the docs of there functions gets you a better understanding how to handle url's and how the code below works.
$link = 'http://www.domainname.com/folder1/folder2/folder3/folder4';
$parts = parse_url($link);
$pathParts = explode('/', trim($parts['path'], '/'));
$buffer = "";
foreach ($pathParts as $part) {
$buffer .= $part.'/';
echo $buffer . PHP_EOL;
}
/*
Output:
folder1/
folder1/folder2/
folder1/folder2/folder3/
folder1/folder2/folder3/folder4/
*/
You should have a look on explode() function
array explode ( string $delimiter , string $string [, int $limit ] )
Returns an array of strings, each of
which is a substring of string formed
by splitting it on boundaries formed
by the string delimiter.
Use / as the delimiter.
This is what you are looking for:
$link = 'http://www.domainname.com/folder1/folder2/folder3/folder4';
$domain_and_slash = 'http://www.domainname.com' . '/';
$address_without_site_url = str_replace($domain_and_slash, '', $link);
// this splits the string into an array
$address_without_site_url_array = explode('/', $address_without_site_url);
$folder_adress = '';
// now we loop through the array we have and append each item to the string $folder_adress
foreach ($address_without_site_url_array as $item) {
// function here for example
$folder_adress .= $item.'/';
echo $folder_adress;
}
Hope that helps.
Try this:
$parts = explode("/", "folder1/folder2/folder3/folder4");
$base = "";
for($i=0;$i<count($parts);$i++){
$base .= ($base ? "/" : "") . $parts[$i];
echo $base . "<br/>";
}
I would use preg_match() for regular expression method:
$m = preg_match('%http://([.+?])/([.+?])/([.+?])/([.+?])/([.+?])/?%',$link)
// $m[1]: domain.ext
// $m[2]: folder1
// $m[3]: folder2
// $m[4]: folder3
// $m[5]: folder4
1) List approach: use split to get an array of folders, then concatenate them in a loop.
2) String approach: use strpos with an offset parameter which changes from 0 to 1 + last position where a slash was found, then use substr to extract the part of the folder string.
EDIT:
<?php
$folders = 'folder1/folder2/folder3/folder4';
function fn($folder) {
echo $folder, "\n";
}
echo "\narray approach\n";
$folder_array = split('/', $folders);
foreach ($folder_array as $folder) {
if ($result != '')
$result .= '/';
$result .= $folder;
fn($result);
}
echo "\nstring approach\n";
$pos = 0;
while ($pos = strpos($folders, '/', $pos)) {
fn(substr($folders, 0, $pos++));
}
fn($folders);
?>
If I had time, I could do a cleaner job. But this works and gets across come ideas: http://codepad.org/ITJVCccT
Use parse_url, trim, explode, array_pop, and implode

Best way to automatically remove comments from PHP code

What’s the best way to remove comments from a PHP file?
I want to do something similar to strip-whitespace() - but it shouldn't remove the line breaks as well.
For example,
I want this:
<?PHP
// something
if ($whatsit) {
do_something(); # we do something here
echo '<html>Some embedded HTML</html>';
}
/* another long
comment
*/
some_more_code();
?>
to become:
<?PHP
if ($whatsit) {
do_something();
echo '<html>Some embedded HTML</html>';
}
some_more_code();
?>
(Although if the empty lines remain where comments are removed, that wouldn't be OK.)
It may not be possible, because of the requirement to preserve embedded HTML - that’s what’s tripped up the things that have come up on Google.
I'd use tokenizer. Here's my solution. It should work on both PHP 4 and 5:
$fileStr = file_get_contents('path/to/file');
$newStr = '';
$commentTokens = array(T_COMMENT);
if (defined('T_DOC_COMMENT')) {
$commentTokens[] = T_DOC_COMMENT; // PHP 5
}
if (defined('T_ML_COMMENT')) {
$commentTokens[] = T_ML_COMMENT; // PHP 4
}
$tokens = token_get_all($fileStr);
foreach ($tokens as $token) {
if (is_array($token)) {
if (in_array($token[0], $commentTokens)) {
continue;
}
$token = $token[1];
}
$newStr .= $token;
}
echo $newStr;
Use php -w <sourcefile> to generate a file stripped of comments and whitespace, and then use a beautifier like PHP_Beautifier to reformat for readability.
$fileStr = file_get_contents('file.php');
foreach (token_get_all($fileStr) as $token ) {
if ($token[0] != T_COMMENT) {
continue;
}
$fileStr = str_replace($token[1], '', $fileStr);
}
echo $fileStr;
Here's the function posted above, modified to recursively remove all comments from all PHP files within a directory and all its subdirectories:
function rmcomments($id) {
if (file_exists($id)) {
if (is_dir($id)) {
$handle = opendir($id);
while($file = readdir($handle)) {
if (($file != ".") && ($file != "..")) {
rmcomments($id . "/" . $file); }}
closedir($handle); }
else if ((is_file($id)) && (end(explode('.', $id)) == "php")) {
if (!is_writable($id)) { chmod($id, 0777); }
if (is_writable($id)) {
$fileStr = file_get_contents($id);
$newStr = '';
$commentTokens = array(T_COMMENT);
if (defined('T_DOC_COMMENT')) { $commentTokens[] = T_DOC_COMMENT; }
if (defined('T_ML_COMMENT')) { $commentTokens[] = T_ML_COMMENT; }
$tokens = token_get_all($fileStr);
foreach ($tokens as $token) {
if (is_array($token)) {
if (in_array($token[0], $commentTokens)) { continue; }
$token = $token[1]; }
$newStr .= $token; }
if (!file_put_contents($id, $newStr)) {
$open = fopen($id, "w");
fwrite($open, $newStr);
fclose($open);
}
}
}
}
}
rmcomments("path/to/directory");
A more powerful version: remove all comments in the folder
<?php
$di = new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($di);
$fileArr = [];
foreach($it as $file) {
if(pathinfo($file, PATHINFO_EXTENSION) == "php") {
ob_start();
echo $file;
$file = ob_get_clean();
$fileArr[] = $file;
}
}
$arr = [T_COMMENT, T_DOC_COMMENT];
$count = count($fileArr);
for($i=1; $i < $count; $i++) {
$fileStr = file_get_contents($fileArr[$i]);
foreach(token_get_all($fileStr) as $token) {
if(in_array($token[0], $arr)) {
$fileStr = str_replace($token[1], '', $fileStr);
}
}
file_put_contents($fileArr[$i], $fileStr);
}
/*
* T_ML_COMMENT does not exist in PHP 5.
* The following three lines define it in order to
* preserve backwards compatibility.
*
* The next two lines define the PHP 5 only T_DOC_COMMENT,
* which we will mask as T_ML_COMMENT for PHP 4.
*/
if (! defined('T_ML_COMMENT')) {
define('T_ML_COMMENT', T_COMMENT);
} else {
define('T_DOC_COMMENT', T_ML_COMMENT);
}
/*
* Remove all comment in $file
*/
function remove_comment($file) {
$comment_token = array(T_COMMENT, T_ML_COMMENT, T_DOC_COMMENT);
$input = file_get_contents($file);
$tokens = token_get_all($input);
$output = '';
foreach ($tokens as $token) {
if (is_string($token)) {
$output .= $token;
} else {
list($id, $text) = $token;
if (in_array($id, $comment_token)) {
$output .= $text;
}
}
}
file_put_contents($file, $output);
}
/*
* Glob recursive
* #return ['dir/filename', ...]
*/
function glob_recursive($pattern, $flags = 0) {
$file_list = glob($pattern, $flags);
$sub_dir = glob(dirname($pattern) . '/*', GLOB_ONLYDIR);
// If sub directory exist
if (count($sub_dir) > 0) {
$file_list = array_merge(
glob_recursive(dirname($pattern) . '/*/' . basename($pattern), $flags),
$file_list
);
}
return $file_list;
}
// Remove all comment of '*.php', include sub directory
foreach (glob_recursive('*.php') as $file) {
remove_comment($file);
}
If you already use an editor like UltraEdit, you can open one or multiple PHP file(s) and then use a simple Find&Replace (Ctrl + R) with the following Perl regular expression:
(?s)/\*.*\*/
Beware the above regular expression also removes comments inside a string, i.e., in echo "hello/*babe*/"; the /*babe*/ would be removed too. Hence, it could be a solution if you have few files to remove comments from. In order to be absolutely sure it does not wrongly replace something that is not a comment, you would have to run the Find&Replace command and approve each time what is getting replaced.
Bash solution: If you want to remove recursively comments from all PHP files starting from the current directory, you can write this one-liner in the terminal. (It uses temp1 file to store PHP content for processing.)
Note that this will strip all white spaces with comments.
find . -type f -name '*.php' | while read VAR; do php -wq $VAR > temp1 ; cat temp1 > $VAR; done
Then you should remove temp1 file after.
If PHP_BEAUTIFER is installed then you can get nicely formatted code without comments with
find . -type f -name '*.php' | while read VAR; do php -wq $VAR > temp1; php_beautifier temp1 > temp2; cat temp2 > $VAR; done;
Then remove two files (temp1 and temp2).
Following upon the accepted answer, I needed to preserve the line numbers of the file too, so here is a variation of the accepted answer:
/**
* Removes the php comments from the given valid php string, and returns the result.
*
* Note: a valid php string must start with <?php.
*
* If the preserveWhiteSpace option is true, it will replace the comments with some whitespaces, so that
* the line numbers are preserved.
*
*
* #param string $str
* #param bool $preserveWhiteSpace
* #return string
*/
function removePhpComments(string $str, bool $preserveWhiteSpace = true): string
{
$commentTokens = [
\T_COMMENT,
\T_DOC_COMMENT,
];
$tokens = token_get_all($str);
if (true === $preserveWhiteSpace) {
$lines = explode(PHP_EOL, $str);
}
$s = '';
foreach ($tokens as $token) {
if (is_array($token)) {
if (in_array($token[0], $commentTokens)) {
if (true === $preserveWhiteSpace) {
$comment = $token[1];
$lineNb = $token[2];
$firstLine = $lines[$lineNb - 1];
$p = explode(PHP_EOL, $comment);
$nbLineComments = count($p);
if ($nbLineComments < 1) {
$nbLineComments = 1;
}
$firstCommentLine = array_shift($p);
$isStandAlone = (trim($firstLine) === trim($firstCommentLine));
if (false === $isStandAlone) {
if (2 === $nbLineComments) {
$s .= PHP_EOL;
}
continue; // Just remove inline comments
}
// Stand-alone case
$s .= str_repeat(PHP_EOL, $nbLineComments - 1);
}
continue;
}
$token = $token[1];
}
$s .= $token;
}
return $s;
}
Note: this is for PHP 7+ (I didn't care about backward compatibility with older PHP versions).
For Ajax and JSON responses, I use the following PHP code, to remove comments from HTML/JavaScript code, so it would be smaller (about 15% gain for my code).
// Replace doubled spaces with single ones (ignored in HTML any way)
$html = preg_replace('#(\s){2,}#', '\1', $html);
// Remove single and multiline comments, tabs and newline chars
$html = preg_replace(
'#(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|((?<!:)//.*)|[\t\r\n]#i',
'',
$html
);
It is short and effective, but it can produce unexpected results, if your code has bad syntax.
Run the command php --strip file.php in a command prompt (for example., cmd.exe), and then browse to WriteCodeOnline.
Here, file.php is your own file.
In 2019 it could work like this:
<?php
/* hi there !!!
here are the comments */
//another try
echo removecomments('index.php');
/* hi there !!!
here are the comments */
//another try
function removecomments($f){
$w=Array(';','{','}');
$ts = token_get_all(php_strip_whitespace($f));
$s='';
foreach($ts as $t){
if(is_array($t)){
$s .=$t[1];
}else{
$s .=$t;
if( in_array($t,$w) ) $s.=chr(13).chr(10);
}
}
return $s;
}
?>
If you want to see the results, just let's run it first in XAMPP, and then you get a blank page, but if you right click and click on view source, you get your PHP script ... it's loading itself and it's removing all comments and also tabs.
I prefer this solution too, because I use it to speed up my framework one file engine "m.php" and after php_strip_whitespace, all source without this script I observe is slowest: I did 10 benchmarks, and then I calculate the math average (I think PHP 7 is restoring back the missing cr_lf's when it is parsing or it is taking a while when these are missing).
php -w or php_strip_whitespace($filename);
documentation
The catch is that a less robust matching algorithm (simple regex, for instance) will start stripping here when it clearly shouldn't:
if (preg_match('#^/*' . $this->index . '#', $this->permalink_structure)) {
It might not affect your code, but eventually someone will get bit by your script. So you will have to use a utility that understands more of the language than you might otherwise expect.

Categories