|
Tots posted:... 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); } ?> 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 */ } ?> 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 |
# ? Feb 23, 2009 20:10 |
|
|
# ? May 16, 2024 18:43 |
|
^Thanks. Very helpful.Internet Headache posted:http://php.net/opendir 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 |
# ? Feb 23, 2009 20:13 |
|
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` 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 |
# ? Feb 23, 2009 20:46 |
|
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!?!' 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.
|
# ? Feb 23, 2009 21:31 |
|
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:
|
# ? Feb 23, 2009 22:17 |
|
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: "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.'; } } ?>
|
# ? Feb 23, 2009 22:27 |
|
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); } } ?> 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?
|
# ? Feb 23, 2009 22:37 |
|
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.
|
# ? Feb 23, 2009 22:50 |
|
VerySolidSnake posted:Changed the code to: 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); ?>
|
# ? Feb 23, 2009 23:00 |
|
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} )?> Just noticed I've been beaten to saying this, but whatever, I've typed it now.
|
# ? Feb 23, 2009 23:52 |
|
Awesome, thank you for the examples and explanations, now that I have something working I'm starting to understand this better.
|
# ? Feb 24, 2009 00:14 |
|
Tots posted:All I want is a listing of files in a directory. 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 |
# ? Feb 24, 2009 00:29 |
|
Zorilla posted:Way late, I know, but this is much easier than others have demonstrated: 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 |
# ? Feb 24, 2009 04:32 |
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!
|
|
# ? Feb 24, 2009 06:04 |
|
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().
|
# ? Feb 24, 2009 07:35 |
|
niralisse posted:Not if you use exec() with an &$output argument. 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.
|
# ? Feb 24, 2009 07:48 |
|
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 "-"
|
# ? Feb 25, 2009 08:11 |
|
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 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 |
# ? Feb 25, 2009 09:50 |
|
Zorilla posted:Way late, I know, but this is much easier than others have demonstrated: 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/> ';?> 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/>';?> Tots fucked around with this message at 16:31 on Feb 25, 2009 |
# ? Feb 25, 2009 15:54 |
|
Tots posted:
You could chdir() to the one you want to search.
|
# ? Feb 25, 2009 17:38 |
|
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?
|
# ? Feb 25, 2009 19:03 |
|
Tots posted:Does anyone know how to search directories other than the current with glob? 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($files, glob($path . '/{*.jpg,*.gif,*.png}', GLOB_BRACE)); } var_dump($files); ?>
|
# ? Feb 25, 2009 19:06 |
|
Tots posted:The number of functions available is loving huge. Do people remember all of these?
|
# ? Feb 25, 2009 19:07 |
|
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?
|
# ? Feb 25, 2009 19:16 |
|
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? 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.
|
# ? Feb 25, 2009 19:21 |
|
gibbed posted:Very simple. Tots fucked around with this message at 21:44 on Feb 25, 2009 |
# ? Feb 25, 2009 21:39 |
|
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($paths, glob($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($files, glob($path . '/{*.jpg,*.gif,*.png}', GLOB_BRACE)); } var_dump($files); ?>
|
# ? Feb 25, 2009 22:38 |
|
Thanks, that was immensely helpful.
|
# ? Feb 25, 2009 23:22 |
|
gibbed posted:
If you are using php5, then please use the spl directoryIterator (http://www.phpro.org/tutorials/Introduction-to-SPL-DirectoryIterator.html).
|
# ? Feb 25, 2009 23:55 |
|
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(0, count($files)); ?> <img src="BunnyPics/<?php echo $files[$selected_image]; ?>" alt="" style="margin: 0 auto;" /> 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 |
# ? Feb 26, 2009 00:08 |
|
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)
|
# ? Feb 26, 2009 00:31 |
|
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 |
# ? Feb 26, 2009 00:52 |
|
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?)
|
# ? Feb 26, 2009 00:56 |
|
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? 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 } ?> That if will return false with $_POST["user"] with or without spaces.
|
# ? Feb 26, 2009 18:46 |
|
awdio posted:Only problem is that I haven't had preg_match work correctly at accepting spaces. It works other wise. 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); ?> php:<? if(strpos($temp, ' ') !== FALSE)?> 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 |
# ? Feb 26, 2009 20:04 |
|
KuruMonkey posted:I would do this: /^[\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); ?> 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 |
# ? Feb 26, 2009 20:29 |
|
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.
|
# ? Feb 26, 2009 20:40 |
|
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.
|
# ? Feb 26, 2009 20:51 |
|
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.
|
# ? Feb 26, 2009 20:54 |
|
|
# ? May 16, 2024 18:43 |
|
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(); ?> 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 |
# ? Feb 26, 2009 22:19 |