Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Tad Naff
Jul 8, 2004

I told you you'd be sorry buying an emoticon, but no, you were hung over. Well look at you now. It's not catching on at all!
:backtowork:

Tots posted:

...
Can someone give me a hint?

Ah well, first thing is that opendir() returns a "directory handle" that you need to keep track of in order to use readdir(). Second thing is that PHP, like a lot of other languages, has assignments that return a value, so $a in "$a=($b=4);" has the value 4. So to make the first example more readable,
php:
<?
$dh=opendir('/whatever'); //$dh is directory handle
if($dh){ // if $dh has a value
 /* process directory */
 closedir($dh);
}
?>
BTW "$path" wasn't the greatest choice of variable name in the first example. If you "echo $path;" you'll get "Resource id #2" or something.

readdir() lets you walk through a directory or reset the cursor or whatnot. 99% of the time you just use it like:
php:
<?
while(($entry=readdir($dh)) !== false){
  /* do something with $entry */
}
?>
The while expression first sets the value of $entry, then tests that against false. (Side note, you test against false explicitly just in case you have some funky entry that evaluates to false. Not sure how that might happen, but eh.) Also to pick on the example code further, readdir() returns both directories and files, so using "$file" isn't quite right.

It's sort of like PET BASIC, if you're old like me. A floppy's directory was stored in a special file called "$", so if you wanted to list the contents of the disk programatically you'd open the file "$", read in each line, then close "$". In PHP, they just built a special command around "$", so opendir() ~= fopen(), readdir() ~= fgets(), and closedir() ~= fclose().

Edit: moved closedir to inside of if

Tad Naff fucked around with this message at 20:32 on Feb 23, 2009

Adbot
ADBOT LOVES YOU

Tots
Sep 3, 2007

:frogout:
^Thanks. Very helpful.

Internet Headache posted:

http://php.net/opendir
php:
<?
$dh = opendir('/home/thetotsn/public_html/BunnyPics/');

while (false !== ($file = readdir($dh))) {
    echo "$file\n";
}
closedir($dh);
?>
opendir() returns a directory handle (dh).

Okay, I think I get it. Then readdir just references that.

IE: I echo'd $dh and it returns Resource id #1. So readdir doesn't use a pathname it uses that handle.

Tots fucked around with this message at 20:16 on Feb 23, 2009

KuruMonkey
Jul 23, 2004

royallthefourth posted:

I'm not too sure about what you already wrote, but how about using the backtick (`) to execute a command and use its results? As in `ls /home/royallthefourth/porn`

Anyone see any problems with that approach?

Do you mean apart from 'what if that code is run under windows?', 'what if that code is run anywhere the PHP user doesn't have permission to use ls?' and the biggie; 'Oh god you aren't EVER going to parameterise that path from something a user enters ARE YOU!?!'

Other than those issues, no; that code's awesome.

Filesystem abstractions abstract the filesystem for a reason.

KuruMonkey fucked around with this message at 20:49 on Feb 23, 2009

Tots
Sep 3, 2007

:frogout:

KuruMonkey posted:

Do you mean apart from 'what if that code is run under windows?', 'what if that code is run anywhere the PHP user doesn't have permission to use ls?' and the biggie; 'Oh god you aren't EVER going to parameterise that path from something a user enters ARE YOU!?!'

Other than those issues, no; that code's awesome.

Filesystem abstractions abstract the filesystem for a reason.

I'm just amazed to know that executing system commands on my host is possible. I probably won't have any use for that anyway, because it will be harder to put in an array.

indulgenthipster
Mar 16, 2004
Make that a pour over
Need some help on figuring this out. I'm trying to simply split up my code into functions, to easily come back and edit them. Here is the code I'm trying to use:

code:
<?
function db_connect() {
	global $link;
	$link = mysqli_connect('localhost', 'user', 'pass', 'db');
	
	global $test;
	$test = "omg lolz";
	
	if (!$link) {
	   printf("Can't connect to MySQL Server. Errorcode: %s\n", mysqli_connect_error());
	   exit;
	} 					
}

function simplequery() { 
	if ($result = mysqli_query($link, 'SELECT firstname FROM edu_user')) {
	
		echo "First names are: ";
	
		while( $row = mysqli_fetch_assoc($result) ){
			echo $row['firstname'];
		}
	
		mysqli_free_result($result); 
	}
}

function test() {
 echo $test;
}

?>
What I can't figure out is why simplequery() doesn't work, because of $link not transferring through. Also, when I call test() on my page, it doesn't echo "omg lolz". These basics are really confusing me, but once I get them I can get going on this!

Tad Naff
Jul 8, 2004

I told you you'd be sorry buying an emoticon, but no, you were hung over. Well look at you now. It's not catching on at all!
:backtowork:

VerySolidSnake posted:

Need some help on figuring this out. I'm trying to simply split up my code into functions, to easily come back and edit them. Here is the code I'm trying to use:

code:
<?
function db_connect() {
	global $link;
	$link = mysqli_connect('localhost', 'user', 'pass', 'db');
	
	global $test;
	$test = "omg lolz";
	
	if (!$link) {
	   printf("Can't connect to MySQL Server. Errorcode: %s\n", mysqli_connect_error());
	   exit;
	} 					
}

function simplequery() { 
	if ($result = mysqli_query($link, 'SELECT firstname FROM edu_user')) {
	
		echo "First names are: ";
	
		while( $row = mysqli_fetch_assoc($result) ){
			echo $row['firstname'];
		}
	
		mysqli_free_result($result); 
	}
}

function test() {
 echo $test;
}

?>
What I can't figure out is why simplequery() doesn't work, because of $link not transferring through. Also, when I call test() on my page, it doesn't echo "omg lolz". These basics are really confusing me, but once I get them I can get going on this!

"global $foo;" means you're using the $foo in the global context. Once you enter a function you lose $foo unless you have a "global $foo;" in there. So you'd need to say "global $test;" in the test() function and "global $link;" in simplequery().

But this is all avoiding the fact that you should avoid global variables if at all possible. Better to return $link in db_connect and use it as a parameter in simple_query, so you can:
php:
<?
function test(){
 $link=db_connect();
 if($link){
  simplequery($link);
 }else{
  echo 'DB connect failed.';
 }
}
?>

indulgenthipster
Mar 16, 2004
Make that a pour over
Changed the code to:

php:
<?
function db_connect() {
    $link = mysqli_connect('localhost', 'user', 'pass', 'db');
    
    if (!$link) {
       printf("Can't connect to MySQL Server. Errorcode: %s\n", mysqli_connect_error());
       exit;
    }                     
}

function simplequery() { 
    $link = db_connect();

    if ($result = mysqli_query($link, 'SELECT firstname FROM edu_users')) {
    
        echo "First names are: ";
    
        while( $row = mysqli_fetch_assoc($result) ){
            echo $row['firstname'];
        }
    
        mysqli_free_result($result); 
    }
}
?>
The error: Warning: mysqli_query() expects parameter 1 to be mysqli, null. What should be changed?

Also another question on writing code like this. When there will be multiple queries, with each having to run db_connect(), won't that just open tons of connections to the database? Shouldn't there be a more efficient way to do this?

spiritual bypass
Feb 19, 2008

Grimey Drawer

VerySolidSnake posted:

won't that just open tons of connections to the database? Shouldn't there be a more efficient way to do this?

You could try using a database abstraction layer. I use MDB2 and its singleton ability.

Tad Naff
Jul 8, 2004

I told you you'd be sorry buying an emoticon, but no, you were hung over. Well look at you now. It's not catching on at all!
:backtowork:

VerySolidSnake posted:

Changed the code to:

[...]

The error: Warning: mysqli_query() expects parameter 1 to be mysqli, null. What should be changed?

Also another question on writing code like this. When there will be multiple queries, with each having to run db_connect(), won't that just open tons of connections to the database? Shouldn't there be a more efficient way to do this?

Still need to "return $link;" in db_connect(). If you want to re-run queries, you don't have to create a new link each time, just reuse $link. For example:
php:
<?
function db_connect() {
    $link = mysqli_connect('localhost', 'user', 'pass', 'db');
    
    if (!$link) {
       printf("Can't connect to MySQL Server. Errorcode: %s\n", mysqli_connect_error());
       exit;
    }
     return $link;                
}

function simplequery($link, $field) { 
    if ($result = mysqli_query($link, 'SELECT '.$field.' FROM edu_users')) {
    
        echo "Values are: ";
    
        while( $row = mysqli_fetch_assoc($result) ){
            echo $row[$field];
        }
    
        mysqli_free_result($result); 
    }
}

$myLink=db_connect();
echo("First Names:\n");
simplequery($myLink,'firstname');
echo("Last Names:\n");
simplequery($myLink,'lastname');
mysqli_close($myLink);
?>
Also, yes, DB abstraction is a good thing.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

VerySolidSnake posted:

Also another question on writing code like this. When there will be multiple queries, with each having to run db_connect(), won't that just open tons of connections to the database? Shouldn't there be a more efficient way to do this?

Can't tell you what the proper way of doing things is, only the way I have picked up of doing things (and that these are apparently two different things has been noted several times in this thread); but what I do is just have a single command at the beginning of the script:

php:
<?
$link = mysqli_connect( {details} )?>
and then keep the variable $link throughout, just using it as an argument whenever I want to do a query. So there's just one connection to the database which I reuse again and again.

Just noticed I've been beaten to saying this, but whatever, I've typed it now.

indulgenthipster
Mar 16, 2004
Make that a pour over
Awesome, thank you for the examples and explanations, now that I have something working I'm starting to understand this better.

Zorilla
Mar 23, 2005

GOING APE SPIT

Tots posted:

All I want is a listing of files in a directory.

...

Can someone give me a hint?
Way late, I know, but this is much easier than others have demonstrated:
php:
<?php

$list glob('/home/thetotsn/public_html/BunnyPics/');

foreach ($list as $file) {
    echo $file."<br />\n";
}

?>

Zorilla fucked around with this message at 00:34 on Feb 24, 2009

Tots
Sep 3, 2007

:frogout:

Zorilla posted:

Way late, I know, but this is much easier than others have demonstrated:
php:
<?php

$list glob('/home/thetotsn/public_html/BunnyPics/');

foreach ($list as $file) {
    echo $file."<br />\n";
}

?>

That is way easier. I wonder why I didn't come across that in my search for a solution.

Wow, additionally you have introduced me to foreach Bye bye loop!

Thanks! :)

Tots fucked around with this message at 04:34 on Feb 24, 2009

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

sonic bed head posted:

If this is all done over regular HTTP and not some fancy vpn certificate or something like that, there has to be a way for you to automate it. How did HTTP Live Headers work out?

It works great now!! HTTP Live Headers helped me understand a bit more about what was going on, Firebug is a little bit confusing when trying to follow the sequence of GETs and POSTs.

Basically how it works is you try to go to google.com and it gives you a 302 response and in the header is something like:
Location: https://wireless.nnu.com/sjsu?sysid=00009183&CLIENT_IP=10.8.x.x

So then you have to do a GET on that URL and that's what gives you the correct _ZopeId. Set the _ZopeId as a cookie and POST the username and password and those other params and you're good to go.

The script can simulate all 3 steps now and it works great. Thanks for showing me HTTP Live Headers!

niralisse
Sep 14, 2003
custom text: never ending story

Tots posted:

I'm just amazed to know that executing system commands on my host is possible. I probably won't have any use for that anyway, because it will be harder to put in an array.

Not if you use exec() with an &$output argument.

The glob() version is probably the way to go. You could also get fancy and use a DirectoryIterator.

For some reason the first results for this problem are always junk like readdir().

Tad Naff
Jul 8, 2004

I told you you'd be sorry buying an emoticon, but no, you were hung over. Well look at you now. It's not catching on at all!
:backtowork:

niralisse posted:

Not if you use exec() with an &$output argument.

The glob() version is probably the way to go. You could also get fancy and use a DirectoryIterator.

For some reason the first results for this problem are always junk like readdir().

Where the heck did DirectoryIterator come from? PHP is such a mindfuck sometimes.

[looks it up] oh, 5.0. I was held back for way too long by sysadmins who wouldn't trust that new PHP 5 (probably with good reason) so I used 4.3.x long past its expire-by date.

LP0 ON FIRE
Jan 25, 2006

beep boop
I've been using preg_match to only accept certain characters, but now I want to use it to accept certain characters AND spaces, but NOT leading spaces, and NOT more than one space in a row. Will that involve more than just preg_match?

I've tried the following to just plain old accept spaces, but it doesn't work! On another forum they showed something similar:

preg_match('%^[A-Za-z0-9_- ]+$%', $_POST["user"])

Notice the space after the "-"

KuruMonkey
Jul 23, 2004
Question: do you really want to 'not accept' leading spaces and multiple spaces? Or just not have them in the final accepted string?

If the second:

php:
<?
$input = ' whatever  it is';
$input = ltrim($input, ' ');
$input = str_replace('  ', ' ', $input);
preg_match($your_current_pattern, $input);
?>
edit: might want a while loop in there to wittle many spaces down to 1? or a preg_replace to do the same?

edit 2: looking at your example it looks like you're going to look up a user name with this...
in that case; coerce the input like above for creating the username, and just allow spaces however when inputting a login that is checked against existing names. In that case you sanitise the input so its safe to use,and just let the fact that you can't create names with multiple or leading spaces mean that you cannot login to one anyway... (you have to handle the 'invalid username' case anyway, why add another for 'impossible username'?

Lastly, to check for wrong spacing only, use:
php:
<?
$coerced = ltrim(str_replace('  ', ' ', $input), ' ');
if(strcmp($input, $coerced) != 0)
{
// oops
}
?>

KuruMonkey fucked around with this message at 09:57 on Feb 25, 2009

Tots
Sep 3, 2007

:frogout:

Zorilla posted:

Way late, I know, but this is much easier than others have demonstrated:
php:
<?php

$list glob('/home/thetotsn/public_html/BunnyPics/');

foreach ($list as $file) {
    echo $file."<br />\n";
}

?>

I went back and rewrote the script using glob() just for fun.

I didn't see any way to search other directories that looked like it would be easy, so I just moved the script to where the files are. Here's what I finally ended up with:

php:
<?
$files = glob('{*.jpg,*.gif,*.png}',GLOB_BRACE);

$max = (count($files)-1);
$random = rand(0,$max);

echo '
<CENTER>
<IMG src="',$files[$random],'"/>
</CENTER>
<BR/>
';?>
as opposed to

php:
<?
$files = array();
$i=0;

    $dh = opendir('/home/thetotsn/public_html/BunnyPics/');

    while (($filename = readdir($dh)) !== FALSE)
        {        
            if ($filename !="." && $filename != "..")
                {
                $files[$i] = $filename;
                $i++;
                }
        }

closedir($dh);

$max = (count($files)-1);
$random = rand(0,$max);

echo '<center><img src="http://72.29.78.167/~thetotsn/BunnyPics/',$files[$random],'" /></center><br/>';?>
E: Mother fucker. I didn't know that when you use require() is like running the script from the current directory. Back to the drawing boards. Does anyone know how to search directories other than the current with glob?

Tots fucked around with this message at 16:31 on Feb 25, 2009

niralisse
Sep 14, 2003
custom text: never ending story

Tots posted:



E: Mother fucker. I didn't know that when you use require() is like running the script from the current directory. Back to the drawing boards. Does anyone know how to search directories other than the current with glob?

You could chdir() to the one you want to search.

Tots
Sep 3, 2007

:frogout:

niralisse posted:

You could chdir() to the one you want to search.

That did the trick.

The number of functions available is loving huge. Do people remember all of these?

gibbed
Apr 10, 2006

Tots posted:

Does anyone know how to search directories other than the current with glob?
Very simple.

php:
<?php
    $files = array();
    $paths = array(realpath('.'));
    while (count($paths) > 0)
    {
        $path array_shift($paths);
        
        $dirs glob($path '/*'GLOB_ONLYDIR);
        foreach ($dirs as $dir)
        {
            $paths[] = $dir;
        }
        
        $files array_merge($filesglob($path '/{*.jpg,*.gif,*.png}'GLOB_BRACE));
    }
    
    var_dump($files);
?>

gibbed
Apr 10, 2006

Tots posted:

The number of functions available is loving huge. Do people remember all of these?
No, gently caress no. No programmer is complete without a manual.

Tots
Sep 3, 2007

:frogout:

gibbed posted:

No, gently caress no. No programmer is complete without a manual.

You just used 3 functions that are completely new to me. I just threw chdir() in my script and it works. Is there any advantage to doing it your way?

gibbed
Apr 10, 2006

Tots posted:

You just used 3 functions that are completely new to me. I just threw chdir() in my script and it works. Is there any advantage to doing it your way?
chdir changes the directory the current process is operating from, depending on what you are doing this can have unintended behavior.

If any of my code is confusing feel free to ask about what you are having trouble with. All my code does is build an array ($files) of absolute paths to all *.jpg/*.gif/*.png files that it finds.

array_merge (merges arrays), array_shift (removes an item from the beginning of the array and returns it), realpath (resolves relative paths to absolute ones).

Use the PHP manual! PHP may have lots of functions but nearly all of them are documented well enough.

Tots
Sep 3, 2007

:frogout:

gibbed posted:

Very simple.

php:
<?php
    $files = array();
    $paths = array(realpath('.'));

//I don't understand why you have this while statement.  Won't realpath('.'); always resolve to a single pathname?
    while (count($paths) > 0)
    {
        $path array_shift($paths);

//Here you are taking the current directory, and searching for any subfolders (I think)
        $dirs glob($path '/*'GLOB_ONLYDIR);
//Now I start to get lost.  I think I'm too tired, and I've been trying to figure out too many things at once today.  What exactly is the statement $paths[] = $dir doing?
        foreach ($dirs as $dir)
        {
            $paths[] = $dir;
        }
//Can you break down what this merge is doing also?
        $files array_merge($filesglob($path '/{*.jpg,*.gif,*.png}'GLOB_BRACE));
    }
    
    var_dump($files);
?>

Tots fucked around with this message at 21:44 on Feb 25, 2009

gibbed
Apr 10, 2006

php:
<?php
    $files = array();
    $paths = array(realpath('.'));

//I don't understand why you have this while statement.  Won't realpath('.'); always resolve to a single pathname?

///Yes, what's happening here is that, as the inner loop runs,
///it will add more paths to the $paths array. The first loop will always 
///happen of course, because I put a starting element in the 
///array (realpath('.'))
    while (count($paths) > 0)
    {
        $path array_shift($paths);

//Here you are taking the current directory, and searching for any subfolders (I think)
//Now I start to get lost.  I think I'm too tired, and I've been trying to figure out too many things at once today.  What exactly is the statement $paths[] = $dir doing?

///This was dumb code on my behalf, I should have just used array_merge. What I'm doing is adding
///found subdirectories to the paths array, so the while loop will search them too, this results
///in every subdirectory from the top directory is searched for files.
///
///The original code, $paths[] = $dir. '$var[] = $thing' is basically syntax magic for array_push($var, $thing).
        $paths array_merge($pathsglob($path '/*'GLOB_ONLYDIR));

//Can you break down what this merge is doing also?
///It's adding all found .jpg/.gif/.png files to the files array (array_merge combines two or more arrays into a single array)
        $files array_merge($filesglob($path '/{*.jpg,*.gif,*.png}'GLOB_BRACE));
    }
    
    var_dump($files);
?>

Tots
Sep 3, 2007

:frogout:
Thanks, that was immensely helpful.

bt_escm
Jan 10, 2001

gibbed posted:

php:
<?php
    $files = array();
    $paths = array(realpath('.'));

//I don't understand why you have this while statement.  Won't realpath('.'); always resolve to a single pathname?

///Yes, what's happening here is that, as the inner loop runs,
///it will add more paths to the $paths array. The first loop will always 
///happen of course, because I put a starting element in the 
///array (realpath('.'))
    while (count($paths) > 0)
    {
        $path array_shift($paths);

//Here you are taking the current directory, and searching for any subfolders (I think)
//Now I start to get lost.  I think I'm too tired, and I've been trying to figure out too many things at once today.  What exactly is the statement $paths[] = $dir doing?

///This was dumb code on my behalf, I should have just used array_merge. What I'm doing is adding
///found subdirectories to the paths array, so the while loop will search them too, this results
///in every subdirectory from the top directory is searched for files.
///
///The original code, $paths[] = $dir. '$var[] = $thing' is basically syntax magic for array_push($var, $thing).
        $paths array_merge($pathsglob($path '/*'GLOB_ONLYDIR));

//Can you break down what this merge is doing also?
///It's adding all found .jpg/.gif/.png files to the files array (array_merge combines two or more arrays into a single array)
        $files array_merge($filesglob($path '/{*.jpg,*.gif,*.png}'GLOB_BRACE));
    }
    
    var_dump($files);
?>



If you are using php5, then please use the spl directoryIterator (http://www.phpro.org/tutorials/Introduction-to-SPL-DirectoryIterator.html).

Zorilla
Mar 23, 2005

GOING APE SPIT

Tots posted:

Does anyone know how to search directories other than the current with glob?

I see a lot of code examples so far, but am I missing something in assuming the solution is much simpler than what I'm seeing others post?

php:
<?php

$files glob("BunnyPics/{*.gif,*.jpg,*.jpeg,*.png}"GLOB_BRACE);
$selected_image rand(0count($files));

?>
<img src="BunnyPics/<?php echo $files[$selected_image]; ?>" alt="" style="margin: 0 auto;" />
If you need recursive file listings like gibbed seemed to be doing, include this function and use it instead (pulled from the comments section of glob() in php.net)
php:
<?php

function rglob($pattern='*'$flags 0$path='') {
    $paths=glob($path.'*'GLOB_MARK|GLOB_ONLYDIR|GLOB_NOSORT);
    $files=glob($path.$pattern$flags);
    foreach ($paths as $path) { $files=array_merge($files,rglob($pattern$flags$path)); }
    return $files;
}

?>

Zorilla fucked around with this message at 00:26 on Feb 26, 2009

gibbed
Apr 10, 2006

Zorilla posted:

If you need recursive file listings like gibbed seemed to be doing, include this function and use it instead (pulled from the comments section of glob() in php.net)
Yeah, what I was doing avoided having to define a function (and would work with any amount of subdirectories, where a recursive function would hit the stack limit eventually).

Zorilla
Mar 23, 2005

GOING APE SPIT

gibbed posted:

Yeah, what I was doing avoided having to define a function (and would work with any amount of subdirectories, where a recursive function would hit the stack limit eventually).

By stack limit, you mean the number of functions running simultaneously, right? One would think you'd hit the limit of the filesystem much sooner than you'd run out of recursions. I can't think of any situation where you'd go 255 directories deep looking for things (or is this limit much lower? I can't find any information about it on Google)

Zorilla fucked around with this message at 00:56 on Feb 26, 2009

gibbed
Apr 10, 2006

Zorilla posted:

By stack limit, you mean the number of functions running simultaneously, right? One would think you'd hit the limit of the filesystem much sooner than you'd run out of recursions. I can't think of any situation where you'd go 255 directories deep looking for things (or is this limit much lower?)
Rather than bother with the possibility of it happening, I wrote to avoid it entirely :).

LP0 ON FIRE
Jan 25, 2006

beep boop

KuruMonkey posted:

Question: do you really want to 'not accept' leading spaces and multiple spaces? Or just not have them in the final accepted string?

If the second:

php:
<?
$input = ' whatever  it is';
$input = ltrim($input, ' ');
$input = str_replace('  ', ' ', $input);
preg_match($your_current_pattern, $input);
?>
edit: might want a while loop in there to wittle many spaces down to 1? or a preg_replace to do the same?

edit 2: looking at your example it looks like you're going to look up a user name with this...
in that case; coerce the input like above for creating the username, and just allow spaces however when inputting a login that is checked against existing names. In that case you sanitise the input so its safe to use,and just let the fact that you can't create names with multiple or leading spaces mean that you cannot login to one anyway... (you have to handle the 'invalid username' case anyway, why add another for 'impossible username'?

Lastly, to check for wrong spacing only, use:
php:
<?
$coerced = ltrim(str_replace('  ', ' ', $input), ' ');
if(strcmp($input, $coerced) != 0)
{
// oops
}
?>


This is some great information for fixing up the spaces. Only problem is that I haven't had preg_match work correctly at accepting spaces. It works other wise.

php:
<?
if(preg_match('%^[A-Za-z0-9_- ]+$%', $_POST["user"])){

}else{
//return false
}
?>
Notice the space after the "-"

That if will return false with $_POST["user"] with or without spaces.

KuruMonkey
Jul 23, 2004

awdio posted:

Only problem is that I haven't had preg_match work correctly at accepting spaces. It works other wise.
php:
<?
if(preg_match('%^[A-Za-z0-9_- ]+$%', $_POST["user"])){
?>

Your problem is actually the - character:

php.net posted:

If a minus character is required in a class, it must be escaped with a backslash or appear in a position where it cannot be interpreted as indicating a range, typically as the first or last character in the class.

So '%^[A-Za-z0-9_\- ]+$%' should work (underscore to space is being read as a range because of - being a control character in square brackets).

Of course since its the done thing when discussing regex; I would do this:
'/^[a-z\d_\- ]+$/i' because its shorter to type. (and I feel all clever when I use control characters and especially /i for case insensitive)

Nevertheless though; just escape that - and it'll work!

Also; referring to my older post:
php:
<?
$temp = preg_replace('/[ ]{2,}/', ' ', $temp);
?>
Is probably the easiest way to remove multiple-spaces, and obviously if you do want to reject;
php:
<?
if(strpos($temp, '  ') !== FALSE)?>
Oh!and '/^[a-z\d_\-][a-z\d_\- ]*$/i' won't allow the first character to be space.

p.s. as is the real way of discussing regex; I'm sure A; "better" ways to do all this do exist, and B; despite my having tested them all, at least one of these will be flamboyantly wrong!

KuruMonkey fucked around with this message at 20:11 on Feb 26, 2009

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



KuruMonkey posted:

I would do this:
'/^[a-z\d_\- ]+$/i' because its shorter to type. (and I feel all clever when I use control characters and especially /i for case insensitive)

/^[\w\s-]+$/ is better. edit: Unless you really want to limit people to spaces and not any whitespace they might put in. In that case, repalce \s with an actual space.

php:
<?
$temp = preg_replace('/[\s]+/', ' ', $temp);
?>
/^[\w-][\w\s-]*$/ won't allow the first character to be space.

There is a regular expressions thread: http://forums.somethingawful.com/showthread.php?threadid=2948658

Munkeymon fucked around with this message at 20:53 on Feb 26, 2009

LP0 ON FIRE
Jan 25, 2006

beep boop
Thank you KuruMonkey and Munkeymon! I knew about escaping the - character but it never came to me when I saw that! Those condensed expressions are pretty awesome, but I have no idea what's REALLY going on in that, so I'll probably read up about it.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Since preg is just the perl regular expression library stapled onto PHP, the perl docs still apply for the most part: http://www.perl.com/doc/manual/html/pod/perlre.html

The only difference in functionality I can think of offhand is that I know preg_replace does a global replace by default but in perl you would have to add the global flag to the end of the regex to get that behavior.

KuruMonkey
Jul 23, 2004

Munkeymon posted:

/^[\w\s-]+$/ is better.

\w Matches characters with accents which the original didn't, and \s matches all whitespace, so tab etc, which the original didn't.

Adbot
ADBOT LOVES YOU

Nortbot
Aug 19, 2003

It's pretty much my favorite animal.
This has been driving me loving nuts all day. I think I've run into a bug in PHP's PDO library. I have a stored procedure that has 2 input and 1 output. All it does is concat arg1 and arg2 and return it as a string. This is a simple testing stored procedure.

Using PDO's bindParam I should be able to get the output into a string without having to select the @out value in a separate query. However, this does not work:

php:
<?
$msg = '';
$stmt = $db->prepare('CALL sp_test(:username,:name,:out)');
$stmt->bindValue(':username', 'bobs');
$stmt->bindValue(':name', 'bob smith');
$stmt->bindParam(':out', $msg, PDO::PARAM_STR, 255);
$stmt->execute();
?>
The error I get is:
2009-02-26T16:07:52-05:00 INFO (6): SQLSTATE[42000]: Syntax error or access violation: 1414 OUT or INOUT argument 3 for routine db.sp_test is not a variable or NEW pseudo-variable in BEFORE trigger

I tried changing PDO::PARAM_STR to PDO::PARAM_INPUT_OUTPUT and still no go. I found a bug report related to this on php.net from 2006 that is flagged as bogus. I have resolved myself to doing this in 2 steps for now but would love to know if this is even possible with PHP 5.2 / Zend Framework 1.7.

EDIT: This is using MySQL 5.0.67 / PHP 5.2.6

Nortbot fucked around with this message at 22:24 on Feb 26, 2009

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply