I am trying to pull the filename out of a directory without the extension.
I am kludging my way through with the following:
foreach ($allowed_files as $filename) {
$link_filename = substr(basename($filename), 4, strrpos(basename($filename), '.'));
$src_filename = substr($link_filename, 0, strrpos($link_filename) - 4);
echo $src_filename;
}
...But that can't work if the extension string length is more than 3.
I looked around in the PHP docs to no avail.
PHP has a handy pathinfo() function that does the legwork for you here:
foreach ($allowed_files as $filename) {
echo pathinfo($filename, PATHINFO_FILENAME);
}
Example:
$files = array(
'somefile.txt',
'anotherfile.pdf',
'/with/path/hello.properties',
);
foreach ($files as $file) {
$name = pathinfo($file, PATHINFO_FILENAME);
echo "$file => $name\n";
}
Output:
somefile.txt => somefile
anotherfile.pdf => anotherfile
/with/path/hello.properties => hello
try this
function file_extension($filename){
$x = explode('.', $filename);
$ext=end($x);
$filenameSansExt=str_replace('.'.$ext,"",$filename);
return array(
"filename"=>$filenameSansExt,
"extension"=>'.'.$ext,
"extension_undotted"=>$ext
);
}
usage:
$filenames=array("file1.php","file2.inc.php","file3..qwe.e-rt.jpg");
foreach($filenames as $filename){
print_r(file_extension($filename));
echo "\n------\n";
}
output
Array
(
[filename] => file1
[extension] => .php
[extension_undotted] => php
)
------
Array
(
[filename] => file2.inc
[extension] => .php
[extension_undotted] => php
)
------
Array
(
[filename] => file3..qwe.e-rt
[extension] => .jpg
[extension_undotted] => jpg
)
------
list($file) = explode('.', $filename);
Try this:
$noExt = preg_replace("/\\.[^.]*$/", "", $filename);
Edit in response to cletus's comment:
You could change it in one of a few ways:
$noExt = preg_replace("/\\.[^.]*$/", "", basename($filename));
// or
$noExt = preg_replace("/\\.[^.\\\\\\/]*$/", "", $filename);
Yes, PHP needs regex literals...
Related
I have an array something like below:
Array
(
[0] => IA62b066
[1] => IAca99de
[2] => IAafed13
[3] => IA49882c
[4] => IA5c9872
[5] => IA39b3e1
I want to export the only the value from this array to text file. Txt file should display data like this.
IA62b066
IAca99de
IAafed13
IA49882c
IA5c9872
IA39b3e1
I have tried many ways but I could not solve it.
file_put_contents("output/$fileName.txt", print_r($array, true));
Can anybody please help me solve it.
That will create test.txt file in the directory of php script with the content of the array.
<?php
$input = [
'IA62b066',
'IAca99de',
'IAafed13',
'IA49882c',
'IA5c9872',
'IA39b3e1'
];
$filePath = __DIR__ . DIRECTORY_SEPARATOR . 'test.txt';
$content = implode(PHP_EOL, $input);
file_put_contents($filePath, $content);
Try this:
<?php
$myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
foreach($your_array as $value){
fwrite($myfile, $value . '\n');
}
fclose($myfile);
?>
So I have the following situation. In my project folder I got a 'data' folder that contains .json files. These .json files also are structured in nested folders.
Something like:
/data
/content
/data1.json
/data2.json
/project
/data3.json
I'd like to create a function that recursively crawls through the data folder and stores all .json files in one multidimensional array, which makes it relatively easy to add static data for use for my project. So the expected result should be:
$data = array(
'content' => array(
'data1' => <data-from-data1.json>,
'data2' => <data-from-data2.json>
),
'project' => array(
'data3' => <data-from-data3.json>
)
);
UPDATE
I have tried the following, but this only returns the first level:
$data = array();
$directoryArray = scandir('./data');
foreach($directoryArray as $key => $value) {
$data[$key] = $value;
}
Is there a neat way to achieve this?
You should use RecursiveIteratorIterator. Skip some directories like . and .. . After this script loop other subdirectories.
//just to remove extension filename
function removeExtension($filename){
return preg_replace('/\\.[^.\\s]{3,4}$/', '', $filename);
}
$startpath= 'data';
$ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($startpath), RecursiveIteratorIterator::CHILD_FIRST);
$result = [];
foreach ($ritit as $splFileInfo) {
if ($splFileInfo->getFilename() == '.') continue;
if ($splFileInfo->getFilename() == '..') continue;
if ($splFileInfo->isDir()){
$path = [removeExtension($splFileInfo->getFilename()) => []];
}else{
$path = [removeExtension($splFileInfo->getFilename()) => json_decode(file_get_contents($splFileInfo->getPathname(), $splFileInfo->getFilename()))];
}
for ($depth = $ritit->getDepth() - 1; $depth >= 0; $depth--) {
$path = [$ritit->getSubIterator($depth)->current()->getFilename() => $path];
}
$result = array_merge_recursive($result, $path);
}
print_r($result);
My json files contain:
data1.json: {"foo": "foo"}
data2.json: {"bar": "bar"}
data3.json: {"foobar": "foobar"}
The result is:
Array
(
[content] => Array
(
[data1] => stdClass Object
(
[foo] => foo
)
[data2] => stdClass Object
(
[bar] => bar
)
)
[project] => Array
(
[data3] => stdClass Object
(
[foobar] => foobar
)
)
)
You do not really have to use RecursiveIteratorIterator. As a programmer you should always know how to deal with recursive data structures, may it be an xml content, a folder tree or else. You may write a recursive function to handle such tasks.
Recursive functions are functions which call themselves to process through data with multiple layers or dimensions.
For example, scanFolder function below is designed to process contents of a directory, and it calls itself when it is encountered with a sub-directory.
function scanFolder($path)
{
echo "scanning dir: '$path'";
$contents = array_diff(scandir($path), ['.', '..']);
$result = [];
foreach ($contents as $item) {
$fullPath = $path . DIRECTORY_SEPARATOR . $item;
echo "processing '$fullPath'";
// process folder
if (is_dir($fullPath)) {
// process folder contents
$result[$item] = scanFolder($fullPath);
} else {
// for this specific program, you should perform a check here to see if the file is a json
// collect the result
$result[$item] = json_decode(file_get_contents($fullPath));
}
}
return $result;
}
IMO, this is a cleaner and more expressive way to accomplish this task and I wonder what others have to say about this statement.
I think that you can use RecursiveDirectoryIterator, there is an documentation about this class.
Model function:
public function file_upload($folder, $allowed_type, $max_size = 0, $max_width = 0, $max_height = 0)
{
$folder = $this->path . $folder;
$files = array();
$count = 0;
foreach ($_FILES as $key => $value) :
$file_name = is_array($value['name']) ? $value['name'][$count] : $value['name'];
$file_name = $this->global_functions->char_replace($file_name, '_');
$count++;
$config = array(
'allowed_types' => $allowed_type,
'upload_path' => $folder,
'file_name' => $file_name,
'max_size' => $max_size,
'max_width' => $max_width,
'max_height' => $max_height,
'remove_spaces' => TRUE
);
$this->load->library('image_lib');
$this->image_lib->clear();
$this->load->library('upload');
$this->upload->initialize($config);
if (!$this->upload->do_upload($key)) :
$error = array('error' => $this->upload->display_errors());
var_dump($error);
return FALSE;
else :
$file = $this->upload->data();
$files[] = $file['file_name'];
endif;
endforeach;
if(empty($files)):
return FALSE;
else:
return implode(',', $files);
endif;
}
This function is working partially. Files are being uploaded to the selected folder, but I am getting this error: You did not select a file to upload. and getting FALSE as a result? What seems to be a problem? (form is using form_open_multipart)
Please make sure that you have this name of your file tag field:
$key='userfile' //which is name of input type field name
Are any of your file inputs empty when this happens? $_FILES will contain an array of "empty" data if there is no file specified for the input. For example, my file input name is one, and I submitted it without specifying a file:
Array
(
[one] => Array
(
[name] =>
[type] =>
[tmp_name] =>
[error] => 4
[size] => 0
)
)
You should check if the file data is empty before processing the upload. PHP's is_uploaded_file() is useful for this.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
PHP Get all subdirectories of a given directory
I want a drop down menu to show all sub-directories in ./files/$userid/ not just the main folder. For example: /files/$userid/folder1/folder2/
My current code is:
HTML:
<select name="myDirs">
<option value="" selected="selected">Select a folder</option>
PHP:
if (chdir("./files/" . $userid)) {
$dirs = glob('*', GLOB_ONLYDIR);
foreach($dirs as $val){
echo '<option value="'.$val.'">'.$val."</option>\n";
}
} else {
echo 'Changing directory failed.';
}
RecursiveDirectoryIterator should do the trick. Unfortunately, the documentation is not great, so here is an example:
$root = '/etc';
$iter = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($root, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST,
RecursiveIteratorIterator::CATCH_GET_CHILD // Ignore "Permission denied"
);
$paths = array($root);
foreach ($iter as $path => $dir) {
if ($dir->isDir()) {
$paths[] = $path;
}
}
print_r($paths);
This generates the following output on my computer:
Array
(
[0] => /etc
[1] => /etc/rc2.d
[2] => /etc/luarocks
...
[17] => /etc/php5
[18] => /etc/php5/apache2
[19] => /etc/php5/apache2/conf.d
[20] => /etc/php5/mods-available
[21] => /etc/php5/conf.d
[22] => /etc/php5/cli
[23] => /etc/php5/cli/conf.d
[24] => /etc/rc4.d
[25] => /etc/minicom
[26] => /etc/ufw
[27] => /etc/ufw/applications.d
...
[391] => /etc/firefox
[392] => /etc/firefox/pref
[393] => /etc/cron.d
)
You can write your own recursive listing of the directories like:
function expandDirectories($base_dir) {
$directories = array();
foreach(scandir($base_dir) as $file) {
if($file == '.' || $file == '..') continue;
$dir = $base_dir.DIRECTORY_SEPARATOR.$file;
if(is_dir($dir)) {
$directories []= $dir;
$directories = array_merge($directories, expandDirectories($dir));
}
}
return $directories;
}
$directories = expandDirectories(dirname(__FILE__));
print_r($directories);
You can use a recursive glob implementation like in this function:
function rglob($pattern='*', $path='', $flags = 0) {
$paths=glob($path.'*', GLOB_MARK|GLOB_ONLYDIR|GLOB_NOSORT);
$files=glob($path.$pattern, $flags);
foreach ($paths as $path) {
$files=array_merge($files,rglob($pattern, $path, $flags));
}
return $files;
}
I am having some trouble with php.
I have a variable $image that contains a url, like
$image='http://example.com/image.jpg'
I am trying to change the name of the image to this, meanwhile not changing the url:
$image='http://example.com/image01.jpg'
$image='http://example.com/image02.jpg'
$image='http://example.com/image03.jpg'
and so on..
Any idea how I can do this?
Or should I use some Javascript?
Code:
$link = 'http://example.com/image.jpg';
for($i=1;$i<=3;$i++) {
$array[] = str_replace('.jpg',sprintf("%02d",$i).'.jpg',$link);
}
print_r($array);
Result:
Array
(
[0] => http://example.com/image01.jpg
[1] => http://example.com/image02.jpg
[2] => http://example.com/image03.jpg
)
EDIT
This works regardless of extension:
$link = 'http://example.com/image.png';
for($i=1;$i<=3;$i++) {
$array[] = substr_replace($link,sprintf("%02d",$i),strripos($link,'.'),0);
}
print_r($array);
Result:
Array
(
[0] => http://example.com/image01.png
[1] => http://example.com/image02.png
[2] => http://example.com/image03.png
)
This will add numbering before last . whichever is the $image file extension
$image = 'http://example.com/image.jpg';
$pos = strripos($image, '.');
$head = substr($image, 0, $pos);
$tail = substr($image, $pos);
for($i=1; $i<=3; $i++) {
$image = $head.sprintf("%02d", $i).$tail;
}