WildCard in PhP

Hi all,
How do I add a wild card syntax in the following PhP string:
I need to search for any xml files starting with the username of the current session - in other words the wild card must be after the username

$signals = [$_SESSION['username'].'.xml'];

Regards
Pierre
Pierre KAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ray PaseurCommented:
http://iconoun.com/demo/temp_pierrek.php
<?php // demo/temp_pierrek.php

/**
 * http://www.experts-exchange.com/questions/28699280/WildCard-in-PhP.html
 */
error_reporting(E_ALL);
echo '<pre>';


// A LIST OF STRINGS TO SEARCH
$tgts = array
( 'Hello kitty'
, 'Fat Albert'
, 'Now is the time for all fatuous men'
, '123'
)
;

// A THING TO SEARCH FOR
$qry = 'fat';

// CREATE A REGULAR EXPRESSION TO SEARCH EACH QUERY STRING IN EACH OF THE TARGETS
$rgx
= '#'              // REGEX DELIMITER
. preg_quote($qry) // SEARCH STRING
. '#'              // REGEX DELIMITER
;

foreach ($tgts as $target)
{
    echo PHP_EOL . $target;
    if (preg_match($rgx, $target)) echo " FOUND REGEX: $rgx";
}

// DO IT AGAIN, CASE-INSENSITIVE
$rgx
= '#'              // REGEX DELIMITER
. preg_quote($qry) // SEARCH STRING
. '#'              // REGEX DELIMITER
. 'i'              // MODIFIER FLAG - CASE-INSENSITIVE
;

foreach ($tgts as $target)
{
    echo PHP_EOL . $target;
    if (preg_match($rgx, $target)) echo " FOUND REGEX: $rgx";
}

Open in new window

0
hieloCommented:
Try adding an else clause and add regex support:
<?php // demo/temp_pierrek.php

/**
 * http://www.experts-exchange.com/questions/28699216/Populate-listbox-with-filenames-on-webserver-in-PhP-HTML.html
 * http://php.net/manual/en/class.recursivedirectoryiterator.php#85805
 * http://php.net/manual/en/class.splfileinfo.php
 *
 * Put this script in the top-level directory
 */
error_reporting(E_ALL);


// THE DESIRABLE FILE NAMES ARE KEPT IN AN ARRAY
//should be able to find 123*.xml
$signals = [$_SESSION['username'].'*.xml'=>'regex', 'error_log', 'php.ini', 'EE_di.txt'];

// THE OPTION STATEMENTS ARE COLLECTED IN AN ARRAY
$options = [];

// COLLECT THE FILE OBJECTS
$path = realpath(getcwd());
$objs = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);

// ITERATE OVER THE OBJECTS TO FIND THE DESIRABLE FILES
foreach($objs as $path => $obj)
{
    $name = $obj->getFileName();
    // this is looking for "exact" matches.
    if (in_array($name, $signals))
    {
        $options[]
        = '<option value="'
        . $path
        . '">'
        . $name
        . '</option>'
        ;
    }
	else
	{      
		foreach($signals as $k=>$v)
		{ 
                        // is you set $signals = [ '123*.xml/'=>'regex', '456*.txt'=>'regex']
                        //the if clause below will get executed
			if( $v==$regex )
			{
				if(preg_match('/'.preg_quote($k,'/') .'/',$name))
				{
					$options[]
					= '<option value="'
					. $path
					. '">'
					. $name
					. '</option>'
					;
				}
			}

                        // is you set $signals = [ '123'], but you have the following files: '123.xml', 'xyz-123.txt'
                        // the if clause below will get executed and will find both, because this is a "contains" filter
			elseif( stripos($name, $v)!==false )
			{
				$options[]
				= '<option value="'
				. $path
				. '">'
				. $name
				. '</option>'
				;
			}
		}
	}
}

// GENERATE THE OPTION STATEMENTS
$opts = implode(PHP_EOL, $options);

// CREATE THE HTML USING HEREDOC NOTATION
$html = <<<EOD
<p>List Box - Single Select<br>
<select name="listbox" size="1">
<option value="">Choose a File</option>
$opts
</select>
</p>
EOD;

// SHOW THE HTML
echo $html;

Open in new window

0
Pierre KAuthor Commented:
Sorry a bit confused
@Ray I'm getting the following result from your code (not in a listbox)
Hello kitty
Fat Albert
Now is the time for all fatuous men
123 FOUND REGEX: #123#
Hello kitty
Fat Albert
Now is the time for all fatuous men
123 FOUND REGEX: #123#i

@hielo - I get nothing in the listbox
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

Ray PaseurCommented:
That's odd.  I did not get that output.  I got this, because the example searched for "fat":
Hello kitty
Fat Albert
Now is the time for all fatuous men FOUND REGEX: #fat#
123
Hello kitty
Fat Albert FOUND REGEX: #fat#i
Now is the time for all fatuous men FOUND REGEX: #fat#i
123

Open in new window

0
hieloCommented:
Should have been:
                  if( $v=='regex' )
                  {
                        if( preg_match('/'. str_replace('/','\\/',$k) .'/',$name) )
                        {

/**
 * http://www.experts-exchange.com/questions/28699216/Populate-listbox-with-filenames-on-webserver-in-PhP-HTML.html
 * http://php.net/manual/en/class.recursivedirectoryiterator.php#85805
 * http://php.net/manual/en/class.splfileinfo.php
 *
 * Put this script in the top-level directory
 */
error_reporting(E_ALL);


// THE DESIRABLE FILE NAMES ARE KEPT IN AN ARRAY
//should be able to find 123*.xml
$signals = Array($_SESSION['username'].'*.xml'=>'regex', 'error_log', 'php.ini', 'EE_di.txt');

// THE OPTION STATEMENTS ARE COLLECTED IN AN ARRAY
$options = Array();

// COLLECT THE FILE OBJECTS
$path = realpath(getcwd());
$objs = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);

// ITERATE OVER THE OBJECTS TO FIND THE DESIRABLE FILES
foreach($objs as $path => $obj)
{
    $name = $obj->getFileName();
    // this is looking for "exact" matches.
    if (in_array($name, $signals))
    {
        $options[]
        = '<option value="'
        . $path
        . '">'
        . $name
        . '</option>'
        ;
    }
	else
	{ //echo 'Searching for '.$name.PHP_EOL;
		foreach($signals as $k=>$v)
		{
            // is you set $signals = [ '123*.xml/'=>'regex', '456*.txt'=>'regex']
            //the if clause below will get executed
			if( $v=='regex' )
			{
				if( preg_match('/'. str_replace('/','\\/',$k) .'/',$name))
				{
					$options[]
					= '<option value="'
					. $path
					. '">'
					. $name
					. '</option>'
					;
				}
			}

            // is you set $signals = [ '123'], but you have the following files: '123.xml', 'xyz-123.txt'
            // the if clause below will get executed and will find both, because this is a "contains" filter
			elseif( stripos($name, $v)!==false )
			{
				$options[]
				= '<option value="'
				. $path
				. '">'
				. $name
				. '</option>'
				;
			}
		}
	}
}

// GENERATE THE OPTION STATEMENTS
$opts = implode(PHP_EOL, $options);

// CREATE THE HTML USING HEREDOC NOTATION
$html = <<<EOD
<p>List Box - Single Select<br>
<select name="listbox" size="1">
<option value="">Choose a File</option>
$opts
</select>
</p>
EOD;

// SHOW THE HTML
echo $html;

Open in new window

0
Pierre KAuthor Commented:
@Ray - Yes I also got that so then I changed the 'fat' to '123' hence the diffrent result
But remember I only want 123*.xml in the listbox not the rest also

@hielo - I replaced but still giving null results. Maybe you can paste the entire code again just to be sure although I'm sure I did replaced correctly
0
Julian HansenCommented:
If all your files are in the same location then this works quite nicely
<?php

$filestring = "{$_SESSION['username']}*.xml";
$files = glob($filestring);
echo "<pre>" . print_r($files, true) . "</pre>";

Open in new window

0
Ray PaseurCommented:
There is quite a learning curve to regular expressions.  It's useful to have good test cases so you can try things easily and learn from the observable examples.

Here is a regular expression, annotated with comments, that finds 123*.xml with the understanding that * = wild card.  You should be able to install it and run it as-is to observe the behavior and see how the regular expression isolates the wild card.
<?php // demo/temp_pierrek.php

/**
 * http://www.experts-exchange.com/questions/28699280/WildCard-in-PhP.html
 */
error_reporting(E_ALL);
echo '<pre>';


// A LIST OF STRINGS TO SEARCH
$tgts = array
( 'Hello kitty'
, '123.xml'
, '123-Foo-xml'
, '123-Foo-.xml'
, '123-.xml'
, '123123123.xml'
)
;

// CREATE A REGULAR EXPRESSION TO SEARCH EACH OF THE TARGETS
$rgx
= '#'              // REGEX DELIMITER
. '123'            // STRING LITERAL
. '('              // START CAPTURE GROUP
. '.'              // ANY CHARACTER
. '+?'             // ONE OR MORE UNGREEDY
. ')'              // END CAPTURE GROUP
. '\.'             // ESCAPED DOT STRING LITERAL
. 'xml'            // STRING LITERAL
. '#'              // REGEX DELIMITER
. 'i'              // MODIFIER FLAG - CASE-INSENSITIVE
;

foreach ($tgts as $target)
{
    echo PHP_EOL . $target;
    if (preg_match($rgx, $target, $match))
    {
        echo " FOUND REGEX: $rgx";
        var_dump($match);
        echo PHP_EOL;
    }
}

Open in new window

0
hieloCommented:
Here's the full example again.  Save it as "Test-hielo.php" and try it.
<?php // demo/temp_pierrek.php
session_start();
$_SESSION['username']=123; // I am putting a "text" value for the username here


/**
 * http://www.experts-exchange.com/questions/28699216/Populate-listbox-with-filenames-on-webserver-in-PhP-HTML.html
 * http://php.net/manual/en/class.recursivedirectoryiterator.php#85805
 * http://php.net/manual/en/class.splfileinfo.php
 *
 * Put this script in the top-level directory
 */
error_reporting(E_ALL);


// THE DESIRABLE FILE NAMES ARE KEPT IN AN ARRAY
//should be able to find 123*.xml
$signals = Array($_SESSION['username'].'*.xml'=>'regex', 'error_log', 'php.ini', 'EE_di.txt');

// THE OPTION STATEMENTS ARE COLLECTED IN AN ARRAY
$options = Array();

// COLLECT THE FILE OBJECTS
$path = realpath(getcwd());
$objs = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);

// ITERATE OVER THE OBJECTS TO FIND THE DESIRABLE FILES
foreach($objs as $path => $obj)
{
    $name = $obj->getFileName();
    // this is looking for "exact" matches.
    if (in_array($name, $signals))
    {
        $options[]
        = '<option value="'
        . $path
        . '">'
        . $name
        . '</option>'
        ;
    }
	else
	{ //echo 'Searching for '.$name.PHP_EOL;
		foreach($signals as $k=>$v)
		{
            // is you set $signals = [ '123*.xml/'=>'regex', '456*.txt'=>'regex']
            //the if clause below will get executed
			if( $v=='regex' )
			{
				if( preg_match('/'. str_replace('/','\\/',$k) .'/',$name))
				{
					$options[]
					= '<option value="'
					. str_replace($_SERVER['DOCUMENT_ROOT'],'', $path)
					. '">'
					. $name
					. '</option>'
					;
				}
			}

            // is you set $signals = [ '123'], but you have the following files: '123.xml', 'xyz-123.txt'
            // the if clause below will get executed and will find both, because this is a "contains" filter
			elseif( stripos($name, $v)!==false )
			{
				$options[]
				= '<option value="'
				. str_replace($_SERVER['DOCUMENT_ROOT'],'', $path)
				. '">'
				. $name
				. '</option>'
				;
			}
		}
	}
}

// GENERATE THE OPTION STATEMENTS
$opts = implode(PHP_EOL, $options);

// CREATE THE HTML USING HEREDOC NOTATION
$html = <<<EOD
<p>List Box - Single Select<br>
<select name="listbox" size="1">
<option value="">Choose a File</option>
$opts
</select>
</p>
EOD;

// SHOW THE HTML
echo $html;

Open in new window

0
Pierre KAuthor Commented:
@Julian - sorry not sure where to include that in my original script

I tried this:
$signals = "{$_SESSION['username']}*.xml";
$files = glob($signals);

But got no result

@hielo - Your new code did give me 123.xml as a result in the listbox but not the 123 Annual.xml I dumped in there to test

@Ray - You are 100% correct that this is a learning curve - seems like I will have to learn much more just to be able to interpret the answers/solutions I get since I'm not always sure how to implement them correctly. BTW - your code gave a lengthily result but not inside a listbox anymore and also not just the 2 files I was expecting.

I thought if I gave the script I have now that it would be enough to have it tweaked to include a wildcard but it seems like changing the line alone is not possible - but needs changes elsewhere as well

I apologize if I'm going about this the wrong way
0
Pierre KAuthor Commented:
@hielo - ahhh good news - I also dumped "test 123.xml" in and now it also gives me that.
So somewhere in your code I have to put the wild card at the back not the front.
Look at my original question stating that the * must be at the back.
Let me have a look...
0
Pierre KAuthor Commented:
@hielo - strangly enough your code seems to have the * at the rear but having dumped the following test files:
123.xml
Test 123,xml
123456.xml
456123.xml
123 Annual.xml

All I'm getting is:
123.xml
456123.xml
Test 123.xml

Not:
123456.xml
123 Annual.xml

Bizarre to say the least
0
hieloCommented:
>> @hielo - Your new code did give me 123.xml as a result in the listbox but not the 123 Annual.xml I dumped in there to test
That's because you need to search for:
123.*\.xml

The "dot" in a regex mean "any character except new line".  To search for a literal dot you need to prefix it with a backslash.

So, if you use:
$signals = Array($_SESSION['username'].'.*\.xml'=>'regex', 'error_log', 'php.ini', 'EE_di.txt');

It will work.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Pierre KAuthor Commented:
Thanks a lot for hanging in there to the end.
With PhP it sure seems to boil down to the little things.
If you don't mind giving it one more look over as now it gives me all the files and not only the ones starting with the Username.
I would like to only get files starting with the Username with nothing in the front. All wild cards must be at the back only.
Thanks again
0
Julian HansenCommented:
@pierre,

Where are your files located relative to the script that is running?

See this example. http://www.marcorpsa.com/ee/t918.php

This works on a folder xml which is in the same folder as the script. The folder has the following files.
user001_000.xml
user001_001.xml
user001_002.xml
user002_020.xml
user002_021.xml
user002_026.xml

Open in new window


Source code is as follows
<?php
session_start();
?>
<!doctype html>
<html>
<head>
</head>
<body>
<?php
$user = isset($_SESSION['user']) ? $_SESSION['user'] : '';
$users = array (
  'user001' => 'User 001',
  'user002' => 'User 002'
);
if (!empty($_POST['user'])) {
  /*******************************/
  /** THIS IS THE IMPORTANT BIT **/
  $_SESSION['user'] = $_POST['user'];
  $filepath = "xml/{$_SESSION['user']}*.xml";
  echo "Searching for {$filepath} ... <br/>";
  $files = glob($filepath);
  /** IMPORTANT BIT ENDS        **/
  /*******************************/
  
  $user = $_SESSION['user'];
  echo "<pre>" . print_r($files, true) . "</pre>";
}

?>
<form method="post">
  <select name="user"> 
    <option value="">-- Select User --</option>
  <?php 
foreach($users as $u => $l) :
    $selected = ($u == $user) ? 'selected="selected"' : '';
    echo <<< HTML
    <option value="{$u}" {$selected}>{$l}</option>
HTML;
  endforeach;
?>
    <br/>
    <input type="submit" />
  </select>
</form>
</body>
</html>

Open in new window

0
Pierre KAuthor Commented:
@Julian - thanks but I think I came right with the help of hielo
BTW - I hope you guys survive the wind there - sounds bad hey!!
0
hieloCommented:
>> I would like to only get files starting with the Username
$signals = Array( '^' . $_SESSION['username'].'.*\.xml'=>'regex', 'error_log', 'php.ini', 'EE_di.txt');

In a regex, the "^" means match at the beginning
0
Pierre KAuthor Commented:
Thanks
0
Pierre KAuthor Commented:
Perfect!!
0
Julian HansenCommented:
BTW - I hope you guys survive the wind there - sounds bad hey!!
So I hear - 'cept not a breath this side of the mountain.
@Julian - thanks but I think I came right with the help of hielo
NP - would be interested to see if glob works - very simple.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.