I'm using the code here - How can I find unused functions in a PHP project (reproduced below) exactly as it is - just the path modified to my location and it behaves as follows:
root#server [/var/www]# php see_unused_code.php
T_STRING
The code used is:
<?php
$functions = array();
$path = "/path/to/my/php/project";
define_dir($path, $functions);
reference_dir($path, $functions);
echo
"<table>" .
"<tr>" .
"<th>Name</th>" .
"<th>Defined</th>" .
"<th>Referenced</th>" .
"</tr>";
foreach ($functions as $name => $value) {
echo
"<tr>" .
"<td>" . htmlentities($name) . "</td>" .
"<td>" . (isset($value[0]) ? count($value[0]) : "-") . "</td>" .
"<td>" . (isset($value[1]) ? count($value[1]) : "-") . "</td>" .
"</tr>";
}
echo "</table>";
function define_dir($path, &$functions) {
if ($dir = opendir($path)) {
while (($file = readdir($dir)) !== false) {
if (substr($file, 0, 1) == ".") continue;
if (is_dir($path . "/" . $file)) {
define_dir($path . "/" . $file, $functions);
} else {
if (substr($file, - 4, 4) != ".php") continue;
define_file($path . "/" . $file, $functions);
}
}
}
}
function define_file($path, &$functions) {
$tokens = token_get_all(file_get_contents($path));
for ($i = 0; $i < count($tokens); $i++) {
$token = $tokens[$i];
if (is_array($token)) {
if ($token[0] != T_FUNCTION) continue;
$i++;
$token = $tokens[$i];
if ($token[0] != T_WHITESPACE) die("T_WHITESPACE");
$i++;
$token = $tokens[$i];
if ($token[0] != T_STRING) die("T_STRING");
$functions[$token[1]][0][] = array($path, $token[2]);
}
}
}
function reference_dir($path, &$functions) {
if ($dir = opendir($path)) {
while (($file = readdir($dir)) !== false) {
if (substr($file, 0, 1) == ".") continue;
if (is_dir($path . "/" . $file)) {
reference_dir($path . "/" . $file, $functions);
} else {
if (substr($file, - 4, 4) != ".php") continue;
reference_file($path . "/" . $file, $functions);
}
}
}
}
function reference_file($path, &$functions) {
$tokens = token_get_all(file_get_contents($path));
for ($i = 0; $i < count($tokens); $i++) {
$token = $tokens[$i];
if (is_array($token)) {
if ($token[0] != T_STRING) continue;
if ($tokens[$i + 1] != "(") continue;
$functions[$token[1]][1][] = array($path, $token[2]);
}
}
}
?>
PHP version is:
PHP 5.3.3 (cli) (built: Aug 7 2010 14:49:50)
You should look at the source code, read it, understand it. Not just coopy-paste-run. Look at the define_file() function definition: if ($token[0] != T_STRING) die("T_STRING");
You can debug it by displaying the file-path where that condition occurs.
if ($token[0] != T_STRING) die("T_STRING: " . $path . " : " . $token[0]);
Then you'll know what the real problem is.
Related
I want to copy a whole folders/files tree from one location to another, but for a particular depth I want to perform a transliteration of the destination folder from one language to another.
So for /src/depth1/depth2/depth3/depth4/file I want to transliterate all depth3 folders to another language before copying them over to the destination path.
So I found this little, robust recursive function, which should help me in my task, and then I tried to add a depth control feature so that the transliteration replacement takes place only on depth3 folders. But at first, what I did only added to the depth. Then I thought I found the correct place to add the $depth--;, but unfortunately I can't figure out where to subtract from it in order to start over a new branch...
Could someone help figure this out please?
recurse_copy('TOCOPY/', 'TEST/');
function recurse_copy($src,$dst,$depth = 0) {
echo $src . ' ' . $depth.'<br>';
$dir = opendir($src);
#mkdir($dst);
while(false !== ( $file = readdir($dir)) ) {
$depth++;
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
recurse_copy($src . '/' . $file,$dst . '/' . $file, $depth);
} else {
$depth--;
// copy($src . '/' . $file,$dst . '/' . $file); //I commented this line to save time from copying files again and again while I'm experimenting with the depth control...
}
}
}
closedir($dir);
}
Not tested, but if my understanding is right this should work, plus minus 1 depth.
recurse_copy('TOCOPY/', 'TEST/', 3);
function recurse_copy($src, $dst, $depth = 0) {
echo $src . ' ' . $depth . '<br>';
if ($depth <= 0) {
return;
}
$dir = opendir($src);
#mkdir($dst);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
recurse_copy($src . '/' . $file,$dst . '/' . $file, $depth - 1);
} else {
// copy($src . '/' . $file,$dst . '/' . $file); //I commented this line to save time from copying files again and again while I'm experimenting with the depth control...
}
}
}
closedir($dir);
}
Addition:
This version will rename some directories according to their depth.
recurse_copy_special('TOCOPY/', 'TEST/');
function recurse_copy_special($src, $dst, $depth = 0)
{
echo $src . ' ' . $depth . '<br>';
$base = basename($dst);
$dir = dirname($dst);
if ($depth == 1) {
$dst = $dir . '/' . 'changed1-' . $base;
}
if ($depth == 2) {
$dst = $dir . '/' . 'changed2-' . $base;
}
if ($depth == 3) {
$dst = $dir . '/' . 'changed3-' . $base;
}
$dir = opendir($src);
if (!file_exists($dst)) {
mkdir($dst);
}
while (false !== ($file = readdir($dir))) {
if (($file != '.') && ($file != '..')) {
if (is_dir($src . '/' . $file)) {
recurse_copy_special($src . '/' . $file, $dst . '/' . $file, $depth + 1);
} else {
copy($src . '/' . $file, $dst . '/' . $file);
}
}
}
closedir($dir);
}
recurse_copy('TOCOPY/', 'TEST/', 3);
function recurse_copy($source, $destination, $depth = 0) {
echo "copy $depth from $source to $destination" . PHP_EOL;
if ($depth < 0) {
return;
}
$directory = opendir($source);
if (!$directory) {
return;
}
#mkdir($destination);
while(false !== ($file = readdir($directory))) {
if (in_array($file, ['.', '..'])) {
continue;
}
$currentSourcePath = $source . '/' . $file;
$currentDestinationPath = $destination . '/' . $file;
if (is_dir($currentSourcePath)) {
recurse_copy($currentSourcePath, $currentDestinationPath, $depth - 1);
continue;
}
copy($currentSourcePath, $currentDestinationPath);
}
closedir($directory);
}
I have one little question, this is my code to list all files from a folder and subfolders;
if ($handle = opendir($dir)) {
$allFiles = array();
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
if (is_dir($dir . "/" . $entry)){
$allFiles[] = "D: " . $dir . "/" . $entry;
}else{
$extension = strtoupper(pathinfo($entry, PATHINFO_EXTENSION));
$fileNoExten = pathinfo($entry, PATHINFO_FILENAME);
$directory = substr(str_replace('/', ' > ', $dir), $rootLenOnce + 3);
$listagem .= '<tr>';
$listagem .= "<td><a href='../" . $dir . "/" . $entry . "' ' target='_blank'>" . $entry . "</a></td>";
//$listagem .= "<td><small>" . $directory . "</small></td>";
$listagem .= "<td>" . $extension . "</td>";
$listagem .= "<td><a class='download-cell' href='../".$dir ."/". $entry."' ' download> <i class='fa fa-download' ></i></a></td>";
$listagem .= "<td class='display-none'>" . $fileNoExten . "</td>";
$allFiles[] = "F: " . $dir . "/" . $entry;
$listagem .= '</tr>';
echo "<pre>"; print_r(glob("*.pdf")); echo "</pre>";
}
}
}
closedir($handle);
foreach($allFiles as $value){
$displayName = substr($value, $rootLen + 4);
$fileName = substr($value, 3);
$linkName = str_replace(" ", "%20", substr($value, $pathLen + 3));
if (is_dir($fileName)) {
myScanDirPdf($fileName, $level + 1, strlen($fileName),$rootLenOnce);
}
}
}
return $listagem;
}
what i need is to filtrate the search, to search only .pdf files.
Someone can help me plz!
Thks!
i try with the glob function, but not with great results.
Thks!
When you are looping through each file, you can use
if(stripos($fileName, ".pdf"))
Hope this will help
I have one more suggestion in listing all the files and subfolders.
You can use Recursive Iterator
$folderName = $_POST['folderName'];
$dir = new RecursiveDirectoryIterator($folderName);
$it = new RecursiveIteratorIterator($dir);
foreach ($it as $fileinfo) {
if ($fileinfo->isDir()) {
}elseif ($fileinfo->isFile()) {
$fileName = $fileinfo->getFileName();
if(stripos($fileName, ".pdf")) {
//do what you need to do
}
}
}
id love a little help with the sort function here, im trying to figure it out but cant.
<?php
if ($handle = opendir('uploads')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".."){
sort ($file);
$thelist .= '<li>'.$file.'<img src="uploads/'.$file.$media.'" width="25" height="25"</li>';
}
}
closedir($handle);
}
?>
<ul><?php echo $thelist; ?></ul>
so this doesnt sort...
and the following will, but wont display some files.
im only interested in the sort function for the top code, i paid a guy to write the following half to try to understand the function sort
from what i can figure were suggesting the $file displays for a list then for a photo using the various $.. im stuck with whats stopping the $file from getting alphabeticaly arranged before being told what to display, (the best i got to was a list of the number ones displaying alphabetical (numerical yes) but its not sorting)
function showDir($dir, $i, $lar, $lon, $lin)
{
print("<style>.box { border-style: outset ; border-width: 1px ; border-color: #A3C5CC ; border-radius: 8px ; -moz-border-radius: 8px }</style>") ;
print("<script language='JavaScript'>
<!--
function MM_openBrWindow(theURL,winName,features) { //v2.0
window.open(theURL,winName,features);
}
//-->
</script>") ;
$i++;
if($checkDir = opendir($dir))
{
$cFile = 0;
while($file = readdir($checkDir))
{
if($file != "." && $file != "..")
{
if(!is_dir($dir . "/" . $file))
{
$listFile[$cFile] = $file;
$cFile++;
}
}
}
if(count(#$listFile) > 0)
{
print("<table cellspacing='1' cellpadding='0' border='0'><tr>") ;
sort($listFile);
$x = 0 ;
for($k = 0; $k < count($listFile); $k++)
{
$spacer = "";
for($l = 0; $l < $i; $l++)
$spacer .= " ";
if($x % $lin == 0)
print("</tr><tr>") ;
$img = $listFile[$k] ;
$tmp = explode(".", $img) ;
$x++ ;
if($tmp[1] == 'jpg' OR $tmp[1] == 'bmp' OR $tmp[1] == 'gif' OR $tmp[1] == 'png'
OR $tmp[1] == 'tga' OR $tmp[1] == 'tif' OR $tmp[1] == 'eps')
{
print("<td>") ;
print("<table class='box' bgcolor='#9ABBC1' cellspacing='0' cellpadding='0' border='0' width='" . ($lon+10) . "' height='" . ($lar+27) . "'><tr>") ;
print("<td align='center'><small><b>" . ($k+1) . "</b></small></td></tr><tr>") ;
print("<td align='center'>") ;
$srcimg = $dir . "/" . $spacer . $img ;
list($width, $height, $type, $attr) = getimagesize($srcimg);
print("<a href='#' onClick=\"MM_openBrWindow('display.php?img=$srcimg&lon=$width&lar=$height','','width=" . $width . ",height=" . $height . ",left=100,top=100,scrollbars=no,toolbars=no')\">") ;
print("<img src='" . $srcimg . "' width='" . $lar . "' height='" . $lon . "' alt='" . $img . "' title='" . $img . "' border='0'></a></td>");
print("</tr></table>\n") ;
print("</td>") ;
}
else
$x-- ;
}
print("</tr></table>\n") ;
print("<br><small>" . $k . " Images displayed<b></b></small>") ;
}
closedir($checkDir);
}
}
}
?>
You should use scandir function instead of readdir.
sorting_order By default, the sorted order is alphabetical in
ascending order. If the optional sorting_order is set to
SCANDIR_SORT_DESCENDING, then the sort order is alphabetical in
descending order. If it is set to SCANDIR_SORT_NONE then the result is
unsorted.
<?php
if ($handle = opendir('uploads')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".."){
$files[] = $file;
}
}
sort ($files);
$thelist = '';
foreach ($files as $file) {
$thelist .= '<li>'.$file.'<img src="uploads/'.$file.'" width="25" height="25"</li>';
}
closedir($handle);
}
?>
<ul><?php echo $thelist; ?></ul>
Why does foreach stop after include (second)? Here is my code:
define('MONITORING_MOD', dirname(__FILE__) . '/');
$entries = scandir(MONITORING_MOD);
foreach($entries as $entry) {
if (preg_match('%[a-zA-Z0-9_-]%', $entry)) {
if(is_file(MONITORING_MOD . $entry) && $entry != 'init.php') {
include_once(MONITORING_MOD . $entry);
} else if ($entry != 'init.php') {
$sub_entries = scandir(MONITORING_MOD . $entry);
foreach($sub_entries as $sub_entry) {
echo MONITORING_MOD . $entry . '/' . $sub_entry;
if (preg_match('%[a-zA-Z0-9_-]%', $sub_entry)) {
include(MONITORING_MOD . $entry . '/' . $sub_entry);
}
}
}
}
}
I tried to use include_once, making special function and it did not help.
Another include_once in this code works perfectly and outside foreach too.
The following code counts the number of files inside a folder.
<?php
function folderlist(){
$directoryist = array();
$startdir = './';
//get all image files with a .jpg extension.
$ignoredDirectory[] = '.';
$ignoredDirectory[] = '..';
if (is_dir($startdir)){
if ($dh = opendir($startdir)){
while (($folder = readdir($dh)) !== false){
if (!(array_search($folder,$ignoredDirectory) > -1)){
if (filetype($startdir . $folder) == "dir"){
$directorylist[$startdir . $folder]['name'] = $folder;
$directorylist[$startdir . $folder]['path'] = $startdir;
}
}
}
closedir($dh);
}
}
return($directorylist);
}
$folders = folderlist();
$total_files = 0;
foreach ($folders as $folder){
$path = $folder['path'];
$name = $folder['name'];
$count = iterator_count(new DirectoryIterator($path . $name));
$total_files += $count;
echo '<li>';
echo '<a href="' .$path .'index.php?album=' .$name . '" class="style1">';
echo '<strong>' . $name . '</strong>';
echo ' (' . $count . ' files found)';
echo '</a>';
echo '</li>';
}
echo "Total Files:". $total_files;
?>
However for some reason the count is off by 2. I have a folder with 13 files but this code returns count as 15. For an empty folder, this returns a count of 2.
Can someone point to me the issue with the above snippet?
I'm doing it with DirectoryIterator
$files_in_directory = new DirectoryIterator($path_to_folder);
$c = 0;
foreach($files_in_directory as $file)
{
// We want only files
if($file->isDot()) continue;
if($file->isDir()) continue;
$c++;
}
var_dump($c);
For use as function :
function folderlist($directories = array(), $extensions = array())
{
if(empty($directories))
return false;
$result = array();
$total_count = 0;
foreach($directories as $directory)
{
$files_in_directory = new DirectoryIterator($directory);
$c = 0;
foreach($files_in_directory as $file)
{
// We want only files
if($file->isDot()) continue;
if($file->isDir()) continue;
// This is for php < 5.3.6
$file_extension = pathinfo($file->getFilename(), PATHINFO_EXTENSION);
// If you have php >= 5.3.6 you can use following instead
// $file_extension = $fileinfo->getExtension()
if(in_array($file_extension, $extensions)){
$c++;
$result['directories'][$directory]['files'][$c]['name'] = $file->getFilename();
$result['directories'][$directory]['files'][$c]['path'] = $file->getPath();
$result['directories'][$directory]['count'] = $c;
}
}
$total_count += $c;
}
$result['total_count'] = $total_count;
return $result;
}
Displaying results based on GET superglobal:
if(isset($_GET['album']) && !empty($_GET['album']) && !isset($_GET['listfiles']))
{
// We are in directory view mode
$album = $_GET['album'];
// View all directories and their file count for specified album
$view_directory = folderlist(array($album), array('jpeg', 'jpg', 'log'));
// Loop the folders and display them with file count
foreach ($view_directory['directories'] as $folder_name => $folder_files){
$count = $folder_files['count'];
echo '<li>';
echo '<a href="files.php?album=' . $folder_name . '&listfiles=1" class="style1">';
echo '<strong>' . basename($folder_name) . '</strong>';
echo ' (' . $count . ' files found)';
echo '</a>';
echo '</li>';
}
echo "Total Files:". $get_dir_info['total_count'];
}
elseif(isset($_GET['album'], $_GET['listfiles']) && !empty($_GET['album']))
{
// We are in file view mode for folder
$album = $_GET['album'];
// View all files in directory
$view_files = folderlist(array($album), array('jpeg', 'jpg', 'log'));
echo 'Showing folder content of: <b>'.basename($album).'</b>';
foreach($view_files['directories'][$album]['files'] as $file)
{
$path = $file['path'];
$name = $file['name'];
echo '<li>';
echo '<a href="files.php?file=' . $name . '&path=' . $path . '" class="style1">';
echo '<strong>' . $name . '</strong>';
echo '</a>';
echo '</li>';
}
}
This line is still returning the '.' and '..' vars.
if (!(array_search($folder,$ignoredDirectory) > -1))
see: http://php.net/manual/en/language.types.boolean.php
Try
if (!array_search($folder,$ignoredDirectory))
EDIT:
Also change this:
$ignoredDirectory[] = '.';
$ignoredDirectory[] = '..';
to
$ignoredDirectory = array( '.', '..' );