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
MrEnigma
Aug 30, 2004

Moo!

duz posted:

Uh, you're outputting text instead of an image. Get rid of that html nonsense.

or move the header right before it. One other piece of advice, usually you want your functions to always return data, instead of printing it out. And then do a print/echo/whatever on on the function on your page.

Adbot
ADBOT LOVES YOU

MrEnigma
Aug 30, 2004

Moo!
Is there any extension/package that will do form creation, and then auto detect if the form values were tampered with (ie with firebug or rewriting the page).

I know .NET has something either built in or available, but was wondering besides rolling your own, if there was anything people use with PHP.

I know there is Filter, but that only validates inputs.

MrEnigma
Aug 30, 2004

Moo!

Phase posted:

No matter where I put the function alphanumeric part I always get:
code:
Fatal error:  Call to undefined function alphanumerc() in /var/www/file.php

function alphanumeric($string) {

elseif (!alphanumerc($user)) {

Any ideas? I don't know how to fix this.

Spell it the same way as when you defined it?

MrEnigma
Aug 30, 2004

Moo!

fletcher posted:

I hope you don't get paid much to "design the webpages" since you can't even google 3 words.

http://www.google.com/search?hl=en&safe=off&q=php+phone+format&btnG=Search

To be fair design and development although sometimes combined (sometimes in the same person) are usually at opposite ends of the spectrum. I wouldn't ever expect our design team to be able to do that.

MrEnigma
Aug 30, 2004

Moo!

iCasm posted:

I'm working on a little script to let me download an entire directory as an archive instead of file by file. It's kind of a PHP learning project for me, but here's my first stab at it:
code:
<?php

$loc = $_GET['loc'];
$file = $_GET['file'];

chdir("../$loc");
$sfile = addcslashes($file," ()[]");
$dfile = str_replace(" ","-",$file);

exec("zip -r0 $sfile $sfile");

header("Content-type:application/zip");
header("Content-Disposition:attachment;filename=$dfile.zip");
readfile("$file.zip");

unlink("$file.zip");
?>
The script is working for the most part, but main problem I'm having is that if the download gets canceled, the .zip file gets created but never deleted and hangs around and takes up space.

Also, I'm not sure that my ad hoc text formatting via addcslashes is going to catch all of the cases that might cause problems. Is there another standard method I should be using? What about directories that have an & in the name? How can I pass those through $_GET?

Well you really don't want to drop any variables directly from a GET into a shell command, filter them or do something to prevent that from happening. But if you must do it at least use escapeshellarg (http://us3.php.net/manual/en/function.escapeshellarg.php), this will make it somewhat safe (and prevent you from doing doing addslashes/strreplace).

As far as deleting the file, look into register_shutdown_function, basically when the script dies it will automatically call the function you specify, in this case you would want to have it call a function that calls unlink.

There are also some built in zip functions in php, and if you can use something built in, it's almost always better than having to run stuff directly on the server to get something done, then again the zip stuff might not work for you (http://us3.php.net/manual/en/ref.zip.php)

Edit: Some clarification

MrEnigma fucked around with this message at 21:10 on Jun 1, 2008

MrEnigma
Aug 30, 2004

Moo!

fletcher posted:

In the past I've used some sort of a Message Catalog table in the DB with fields id, language, message. Then create a way to access that, like:

php:
<?
echo MessageCatalog->getMessage("hello", "es");?>
code:
hola
You will probably want to implement some sort of cache so you can store the messages in memory rather than querying the DB for each message every time you use it.

There is also zend framework, which you can use just parts of.

http://framework.zend.com/manual/en/zend.locale.html

MrEnigma
Aug 30, 2004

Moo!

minato posted:

You're probably hitting the PHP 30 second execution time limit.

You can get around this in some cases by doing

set_time_limit(0)

But watch out, since it will basically keep running (well until you stop the browser). Just make sure you don't allow it to be backgrounded also, and then have a run away process :) There are some issues also because fopen (process) can be blocked.

Can you do file_get_contents('file path here'), that pretty much takes everything you do and does it in one easy swoop.

MrEnigma
Aug 30, 2004

Moo!

mcbuttbutt posted:

Nothing regarding that in the logs, plus there are some database updates that occur after the fread() that successfully execute.


Yeah, forgot to mention already having set_time_limit(0). I tried using get_file_contents and saw this error -- PHP Fatal error: Allowed memory size of 12582912 bytes exhausted

Ah, you're running out of memory.

PHP has a memory_limit parameter in php.ini

You can also hit it using

ini_set('memory_limit', '64M');

in a script

or via .htaccess

From: http://drupal.org/node/29268

Granted it's for drupal specifically, but it should work for you also.

Edit: If you're on a shared host that might not work for you. And file_get_contents is probably more memory intensive since it loads up the entire thing, while on the other one you were doing it in chunks.

MrEnigma fucked around with this message at 20:03 on Jun 11, 2008

MrEnigma
Aug 30, 2004

Moo!

mcbuttbutt posted:

Yeah, using get_file_contents() I ran out of memory and got the message in the error log.

However reading it chunk by chunk still doesn't complete the download and following code is executed. Forgive the poor wording, but could it be possible that I'm losing connection with the download once the PHP script stops executing? It's strange that I'm only getting half of the zip file and no errors.

it's dying somehow, it might be because of something else, like a remote host dropping it, or simply php not being able to set a timeout on that process.

you could try raising up your level of reporting...if you're on PHP5 use

error_reporting(E_ALL | E_STRICT);

MrEnigma
Aug 30, 2004

Moo!

functional posted:

This isn't always working like it should. I have a special link on my pages that will take you to loggingout.php. It uses a token to verify that you actually clicked the link (and didn't have anyone IM you a fake logout link). Stripping away the logic what it really does is this, which should log you out and redirect you to the index:

php:
<?
LOGGINGOUT.PHP

setcookie('blargh','',time()-$tenyears,myCookiePath(),myCookieDomain());
header('Location: [url]http://website.com/theindexpage.php[/url]');
?>
Once every few times it takes me to the index page without erasing the cookie. I can tell because the index page does stuff that it would only do if you were logged in properly.

What's the deal?

caching probably, browser still you were cached, try adding some no cache headers and it should fix it.

MrEnigma
Aug 30, 2004

Moo!

functional posted:

Do you mean to add no-caching headers to the page that looks like you're still logged in? There's a lot of different caching stuff you can do. Can you elaborate? Maybe post some source to get me started?

Yeah, to the page that looks like you're still logged in. It's your browser caching that page on you I'm guessing, there are a bunch of them you can find from a google search. But setting the header expiration in php, the meta expire stuff in html, and maybe there are a few more, but that should do it.

MrEnigma
Aug 30, 2004

Moo!

cannibustacap posted:

Then why would they offer a PHP features?

I think the feature is that it can do code foldering and syntax highlighting for PHP. If you think there is more, hit up your manual.

MrEnigma
Aug 30, 2004

Moo!

nbv4 posted:

I want to add a feature on my site that outputs that data into a PDF file, so when the user print, it looks consistent and paged correctly. Anyone know of a good library or something that will do this?

PDFLib is the one you want, it's not easy at all to do things though...well anything besides just a block of text.

http://pecl.php.net/package/pdflib

It's free for non-commercial use (or at least there is a free alternative for non-commercial use).

Edit: Also check out http://us3.php.net/manual/en/book.pdf.php (and the comments).

MrEnigma
Aug 30, 2004

Moo!

bt_escm posted:

take a look at http://www.digitaljunkies.ca/dompdf/

It will convert html + css2.1 to a pdf document and is a crap load easier than directly using PDFLib.

That's awesome, although I don't see a usage license on there...but apparently it's "free" for all.

MrEnigma
Aug 30, 2004

Moo!

passionate dongs posted:

Really dumb question:

I'm outputting the results of a mysql query into a page and loading it into a javascript array. Right now it is essentially like this:

code:
var myArray = [ 
<? while(mysql results) {
  echo("{name: $result},");
} ?>
];
problem is, that there is always one stray comma at the end of the last entry into the array, which makes sense. Outside of writing some really bad code, I am fairly certain there has to be an easy way to output "a, b, c, d, e" instead of "a, b, c, d, e, "

The code works in IE/Firefox/Safari, but of course it produces javascript errors. What is an easy way to say "on the last record truncate the comma" ?

You could always do something like this (as long as it's an array):

code:
echo implode(' ,' $array);

MrEnigma
Aug 30, 2004

Moo!

fletcher posted:

Email your host and ask them to fix this. If they don't, find a new web host.

You usually can just manually include the PEAR files in your script if you can't run the actual pear software, basically the same thing. A lot of hosts won't use the extension, but it doesn't stop you from using the code.

MrEnigma
Aug 30, 2004

Moo!

bt_escm posted:

put the resultset into an array and then have a look at http://www.php.net/json_encode

This works great for encoded arrays for javascript, however I think it requires php 5.2 or higher...

MrEnigma
Aug 30, 2004

Moo!

fletcher posted:

You can grab json_encode.php off PEAR and just include 'json_encode.php';

Ironically my own advice from earlier in the thread, and not sure why I didn't think of that, thanks for the tip.

MrEnigma
Aug 30, 2004

Moo!

Safety Shaun posted:

sample.php, geoip.inc, GeoIP.dat all in the same dir (domain.com/ip2c)
path in sample.php is correct:

$gi = geoip_open("/home/removed/public_html/ip2c/GeoIPCity.dat",GEOIP_STANDARD);

Still not working:


Warning: fopen(/home/removed/public_html/ip2c/GeoIPCity.dat) [function.fopen]: failed to open stream: No such file or directory in /home/removed/public_html/ip2c/geoip.inc on line 314

Line 314 just includes the var $gi


EDIT: Fixed, standard file in the code is GeoIPCity.dat, I just had GeoIP.dat.

The only way this could be failing is if you have the wrong path.

I'm guessing not only do you have a user, but also the domain something like

/home/user/domain.com/public_html/ip2c/GeoIPCity.dat

Edit: if you have shell access, go to the ip2c directory and type 'pwd'

MrEnigma fucked around with this message at 17:45 on Jun 25, 2008

MrEnigma
Aug 30, 2004

Moo!

er0k posted:

You'll run into problems if another script is dependent on it, but otherwise I don't really see why not. You can die with a useful error message as well.

Yeah, it's probably not the best practice as others have said, but really you can do whatever you want (ie php can work that way). I'd recommend throwing an Exception, and potentially catching it someplace else if needed. Although if you don't catch it, you're probably going to end up with a big ugly PHP error on your page.

MrEnigma
Aug 30, 2004

Moo!

Neon Machete posted:

I'm trying to set up a simple PHP script that uploads a file and inserts the filename into an XML document. I have a slideshow system that fetches the image names from the document and puts it up on the slideshow. I'm using DOM XML functions to do this. The problem is, I'm a total newbie with PHP and my host is using an ancient version of PHP (4.1.2).

My xml file is structured like this
code:
<?xml version="1.0" encoding="UTF-8"?>
<gallery>
<album title="Photos" description="Pictures" lgPath="gallery/album1/large/">

<img src="image1.jpg" />
<img src="image2.jpg" />


</album>
</gallery>
All I need to do with my PHP script is insert my image name inside the <album> tags formatted like the others. Uploading works fine. Beyond this, I'm stumped. I've tried different methods for a good 5 hours or so, but nothing works. DOM XML functions vary from version to version but I simply cannot find accurate documentation of them under 4.1.2. It seems really simple based upon the tutorials I have seen for PHP 5. The documentation on the PHP website is all for the later versions of 4. Anyone here well versed in caveman PHP coding?

There are various backports of different things, like for instance PHP 5's SimpleXML class, has been backported to php4 (although you'll still need the XML parser extension)

http://www.ister.org/code/simplexml44/index.html

If you get that working, you can use something like:

http://us2.php.net/manual/en/function.simplexml-element-addChild.php

PHP in general isn't very good in dealing with XML, but with a few tricks you can make it work.

MrEnigma
Aug 30, 2004

Moo!

genericadmin posted:

PHP's foreach is a mess. You need to be really careful with it because of how it performs implicit copies and may screw around with references in unexpected ways. Because PHP has no lexical scope, foreach also does not clean up after itself properly as it does in other languages.

The effects differ depending what version of PHP you are using. I think a for loop is much safer and predictable.

The biggest issue is that referencing switched from PHP4 to PHP5, at least with regard to objects.

In PHP5 objects are always referenced when using '=', arrays are referenced using '=&'
In PHP5 a '=&' on an object makes a 'hard-link',
Example:
$a = new ABC();
$b =& $a;
unset($b);

Edit: I think this might actually be a clone (shallow copy) but it's deprecated in PHP5 regardless.

That will actually unset $a because it's a 'hard-link', just using a normal reference or copy would leave just $b unset.

With regards to a foreach, you can specify to do foreach($array as &$value) which allows you to not copy the array but do it b y reference instead. (the & in front of the $value).

Also be aware that foreach will move the array pointer also (but calling foreach resets it back to the start).

MrEnigma fucked around with this message at 06:37 on Jul 10, 2008

MrEnigma
Aug 30, 2004

Moo!

drcru posted:

Thanks but unfortunately we don't have PHP5 installed yet :(.

How crappy and or efficient are serialize and unserialize?

The array may reach up to 375 items per person and map so I'm a little worried about how well it would handle if there are, worst case, 5000 users and 15 maps.

You can install the JSON stuff through PECL if you want (I believe this will work through PHP4), or ZendFramework has one also.

serialize will work, but then you need to write it out to a file each time. Which will work, but if you have easy access to a mysql db, you should set it up in there.

It could get kind of messy, but you'd have multiple tables.
Users (which contains a users_id, datetime column, place_id, rating, etc)
Places (which contains the places_id, name, location, features about that place, etc)

Pretty easy to join from Users to Places to get your data out, just figure out the user id, select them all out joining on places, ordering by time. If the places are always going to be unique (like long/lat) then you could probably just put that data right in the users table.

MrEnigma
Aug 30, 2004

Moo!

drcru posted:

What are your thoughts on just using implode/explode?

It should work, but then you have to catch all the special cases (like escpaing characters). My feeling that if someone has already wrote the way it should be and thought of all that, why reinvent the wheel, I'll just use that.

MrEnigma
Aug 30, 2004

Moo!

Safety Shaun posted:

Crap, how do I avoid the header already sent spaz out that PHP has when I retrieve and edit (remove) a cookie in the middle of my script. Simply moving it to the top of this script isn't possible because it's an include and the main index.php is outputted before this is called.

php:
<?
{lots of code}
    $prevcorrect = $_COOKIE["cookiename"];
    setcookie("cookiename", 0, time()-604800, "/", ".mydomain.co.uk", 0);
{lots of code}
?>
Or would it be a lot more simple to set a session in the other script, then destory the session here; or would I come up with the same problem?

Sessions would fix this, but they also do not persist for a user when they come back (although you could somehow use a cookie to reactivate a session...or other craziness like that).

A cookie has to be sent in the headers, which means it has to go before any output. This means, you'll either need to figure out a way to get that cookie set at the top of the page (or on a new page), or you need to output buffer the page.

MrEnigma
Aug 30, 2004

Moo!

nbv4 posted:

How do you add a indexed value to an array via indirection?

I have this:

code:
foreach(array(cat1, cat2, cat3), as $category)
{
   [...]

    $$category['xc_dual'] = $temp[0];

}

var_dump($cat1);

The cat1, cat2, etc. arrays are already created and have values. I need to add temp[0] to the end (or beginning, or wherever) and it must be INDEXED. With the above code all that comes out is the original array with no 'xc_dual'.

Whats odd is that I can change that line to:

code:
$$category[] = $temp[0];
and it works perfectly fine, but then it's indexed to "0". This is hosed up as hell.

It's because of how it evaluates.

Variable variables work by doing...

Getting value (string) of $category['xc_dual']
now you have $string

I think what you are assuming this is doing is...
evaluating category to a string, then setting $string['xc_dual'] and it doesn't work that way.

Edit: I just reread what I wrote and it's consuing, but there are some examples of what you want to do on the Variable Variables page.

http://us2.php.net/language.variables.variable

MrEnigma fucked around with this message at 07:53 on Aug 13, 2008

MrEnigma
Aug 30, 2004

Moo!

nbv4 posted:

Oh I see, order of operations. I'm surprised it didnt bring up an error or something... Anyways, I guess a double array is my only option:

$times[$category]['xc_dual'] = $temp[0];

If you increased error_reporting to E_ALL | E_STRICT, it would throw a nice notice for you.

MrEnigma
Aug 30, 2004

Moo!
You could get around this by making all your functions only take in an array, and then parsing out the variables from that OR

You can also use func_get_arg and then have no defined arguments required. This means you'll need to do all your own checking, but it gives you a lot more control.

For code that's already written I just make sure to pass in the would be default values to them. Like instead of passing $show_query or nothing at all, pass in false. It's kind of annoying, but you're probably not going to ever change the defaults the function anyways. And if it's new, you could use one of the two solutions above.

MrEnigma
Aug 30, 2004

Moo!

Ned posted:

PHP has no idea of knowing what the page actually looks like in the browser or DOM. jQuery is your friend here.

PHP actually has an object for manipulating the DOM (http://us.php.net/dom). The catch is that you need to use output buffering, and you have to operate on it before you dump it out to the user.

There is also PHPquery (http://code.google.com/p/phpquery/) which is compatible with jQuery 1.3 API I believe.

MrEnigma
Aug 30, 2004

Moo!

Chopper posted:

This is something I don't get with "Web 2.0" design.

Everyone is so "OMG TABLESSS!!!" that they never use them. I've seem someone display tabular data using floated divs.

You aren't giving in by using tables for displaying data, you are only giving in if you use them for design purposes.

While I completely agree with you about tables and actual data. I can see uses for doing non-tables for data....variable columns, moving stuff way around. Some sites that allow for a theme or something could have some advantage...but yeah...not usually.

MrEnigma
Aug 30, 2004

Moo!

Zorilla posted:

I should have asked about =& specifically since I saw it here. I still can't quite figure out what it's supposed to do differently than = does.

It makes a reference (which you can read about a few posts up..well the link in a few posts up).

Objects by default are referenced just using =, but when a =& is done, they perform a clone (a shallow copy essentially...sometimes called a hard link).

Think of it this way.

$a = 1;
$b =& $a;

$b++;

// $a will be 2 here.
var_dump($a);

if you did $b = $a, $a would still be 1. Instead of holding a value, it basically just links to another variable...a reference. It gets a bit more complicated when you start using references inside objects and passing in to functions, but it's pretty easy.

MrEnigma
Aug 30, 2004

Moo!

sonic bed head posted:

If you wanted a function that could return two values, you couldn't in php, because each function can only return one value to its caller. The way to get around this would be to send in a pointer to the function as a parameter and allow changes to be done on that. I use pointer here as something that is assigned using the =&.

It also helps when you don't want your data being copied all over the place. Say you're operating on a huge array, and instead of passing it in to a function, you could reference it in. It also comes in very handy when you're using recursive functions.

MrEnigma
Aug 30, 2004

Moo!

Scaramouche posted:

I realize that a lot of it is my own expectation about what something should return; the fact that the function returns differing types based on the input is a bit strange but not 'OMG CODING HORROR'. I think what bothers me more is the loosy goosy nature of the comparisons.

Yeah, lots of languages do the -1/false response that will equate to a loose type match that is the same. Javascript has the same issue. It's not the method returning this that is the issue so much (the alternative is to throw an exception?), but the language that enables this to be an issue.

As long as you know about it, and can read the giant warning on php.net, you should be good.

MrEnigma
Aug 30, 2004

Moo!

IT Guy posted:

Oh, I was unaware crypt() did the bcrypt thing, thanks for that.

Unrelated:
Can PHP session variables be spoofed at all by a user?

For example, let's say I authenticate a user and store some information about the user in the session variables such as:

uid
username
hashedpassword

Now, I wan't to display some records based on the id of the user (uid). Can I safely rely on the uid I wrote to the session variables or should I do a lookup of the user with the username and hashed password and get the uid that way? The latter is more secure (I think?) but requires one additional SQL query.

Any thoughts?

Sessions are generally stored server side, unless the option for cookie based sessions is on.

This means the user only has the session, which links up with the data on your side. It's possible for a Man in the Middle attack so someone could spoof the session id, but you have larger problems then, and it's something doing a db lookup isn't going to help with.

I would avoid storing the hashedpassword in the session, as if they have a session with a user id, you could safely assume they are authenticated. Username is also suspect, since then you have to keep the session up to date with any changes that are made. Plus the less data the server has to read off disk for the session the better.

There are some good practices for sessions, like copying the session to a new id on every page load, this helps prevent MitM, but adds server load, and sometimes issues with AJAX/async requests.

MrEnigma
Aug 30, 2004

Moo!

IT Guy posted:

Thanks for that, clears up some confusion. So just to be 100% clear, they could potentially spoof their session ID, but never the variables inside the session since it's stored on the server, correct?

Also this cleared it up for me as well: http://stackoverflow.com/questions/6483092/php-session-hijacking

As for storing the hashed password, what do you guys do if you revoke someones privileges? With your method, the user would stay logged in even if you deleted the user from your database, at least until the session expired. By storing the hashed password in a session variable, I can do a "SELECT COUNT(*) FROM users WHERE username = :username AND password = :password" to make sure they are still in the database.

I've always ended up needing some other data for the user that was in the DB already, so it gets loaded every time, and if not in the db, it fails.

I'd recommend at least checking, this will allow you to grab the username/email/etc that you need as well without clogging up sessions with it.

Adbot
ADBOT LOVES YOU

MrEnigma
Aug 30, 2004

Moo!

Sab669 posted:

Hmm, when I call a getter for one of my properties, the output just says "Array" instead of what I expected (a date).

When a user logs in, I call $instance->setDate(getdate()). Then I redirect them to a page that displays a bunch of information (echo $instance->getDate();), and it should have that Date property of the object, which should be the current date. Instead it just prints out "Array" text.

As I'm typing this I realized I don't even want to set the date when they log in, it should be when they log out, but regardless.. Why would I be getting text?

The date object that is being returned appears to be an array. When you echo an array you get the string 'Array'. print_r/var_dump it instead and you will see the date array.

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