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
Begby
Apr 7, 2005

Light saber? Check. Black boots? Check. Codpiece? Check. He's more machine than kid now.

sivo posted:

Zend_Form. This class seems to "suffer" from the ZF use-at-will design in that it blurs together aspects of the view (decorators) and the model (validation logic) - I just have no idea where to stick my Zend_Forms.

Your model should just be the data and thats it. Ideally if you dropped zend framework and went with code ignitor, you should just be able to take the zend model class and maybe the zend pdo class with you and your models should work fine. If not, then stuff isn't separated like it should be.

Think of it this way, you should be able to code your model so that you could satisfy all requirements of your app by running it through command line scripts and no GUI. If forms became tied to your model this would break. So stick your forms outside the model.


sivo posted:

To me, it looks like B is the way to go, but I can't help but feel worried that I am robbing Controllers of what seems to be, fairly often, their only responsibility (that you write yourself, at least) - that A is so popular doesn't help my confidence in B.

A is the way to go. You want your views to just display data without actually doing any logic. Your controllers should do the querying and decisions.


Overall though, I think I went down the same path as you previously. Just because it is included in Zend, doesn't mean you have to use it. Its good to learn how to use things and learn the theory, but more often than not using all of the framework for everything leads to pattern overuse and unnecessary complexity. Sometimes its better to just hand write forms in HTML instead of using form generators.

Adbot
ADBOT LOVES YOU

KuruMonkey
Jul 23, 2004

sivo posted:

Secondly, what exactly are Controllers supposed to do? It seems like everyone agrees that Controllers should do as little as possible, but where you draw the line seems to differ for everyone. It seems to me that it's either:

Anyone that is saying controllers should do as little as possible is a moron.

MVC is simple:

Model; this is an interface to your data storage (db, csv, inifile, punched card reader - it shouldn't matter AT ALL to anything outside the model). You should have a model per conceptual 'entity' collection in your system; Users, Articles, Images, Newsletters, Gallery Albums - these are all candidates to have a model dedicated to abstracting the work of extracting the data from storage, or making changes to it there.

Controller; this is where the 'business logic' of your application should live. Any decisions being made, this is where it should happen. Controllers decide both which elements of data are required to service the request (i.e. build a page, handle a post) and which views are required to communicate the results back to the user. Controllers are the brains, they are, really, where the application lies.

Views; this is where all data is packeged up and formatted for output. Note that this CAN mean 'formatted to be written to a file' if the file is output not storage (e.g. if your app creates graphs of data, the graph drawing is a view, even if it spits out a jpeg to disk). All presentation logic should be in views, and good frameworks should allow views to delegate presentation to other views. But NO framework should allow views direct access to setup or control models. Also views shouldn't be asking controllers for things; controllers should be invoking views to display/present things.

If you are then changing your app, MVC should, if used right, make the job simple.

Change the look of your app; change views. (i.e. go from html to pdf output; new view)

Change the way your app reads/writes its data; change models. (i.e. go from csv to db storage; new model)

Change the behaviour of your app; change controllers. (i.e. want to make adding a blog post save i in the db and punt a notification to twitter? change the controller to also invoke the view that renders the tweet)

Note the most fundamental change to your app comes if you modify the controller.

If changing from flat files to DB involves a change in the controller; you did it wrong.
If changing from flat files to DB involves a change in a view; you hosed up massively.

sivo posted:

To me, it looks like B is the way to go, but I can't help but feel worried that I am robbing Controllers of what seems to be, fairly often, their only responsibility (that you write yourself, at least) - that A is so popular doesn't help my confidence in B.

B is entirely wrong. You would basically be making the view do the job of the controller as well as the view. Also, everything I have heard about Zend Framework is that it is a bloated and puffy framwork that is overly restrictive and clunky. But has a few nice bits hidden inside it.

KuruMonkey fucked around with this message at 00:28 on May 2, 2009

supster
Sep 26, 2003

I'M TOO FUCKING STUPID
TO READ A SIMPLE GRAPH
Are there any CMS systems that are as elegant and simple as Wordpress that are ideal for simple mostly-static non-blog sites? I like alot of the functionality that Wordpress provides (namely the creating pages on the fly and site-wide settings), but am just curious if there's a better option to use for non-blog sites than to just hide the blog portion of Wordpress.

Zorilla
Mar 23, 2005

GOING APE SPIT

supster posted:

Are there any CMS systems that are as elegant and simple as Wordpress that are ideal for simple mostly-static non-blog sites? I like alot of the functionality that Wordpress provides (namely the creating pages on the fly and site-wide settings), but am just curious if there's a better option to use for non-blog sites than to just hide the blog portion of Wordpress.

Probably CMS Made Simple. It's decent and the only real downside I've noticed is that templates and CSS are stored in the database and there is no separate storage for template images and content images.

I've used Website Baker as well, but its backend is pretty crude in comparison.

sivo
Dec 2, 2003
Life is but a dream
Thanks for the replies. I'm definitely worried about going overboard with patterns/complexity, it's something I think I'm very susceptible to :) (and I know it's not a good thing) It's just a bit of a struggle to understand when all the examples on the internet are very simple and descriptions ambiguous/generic

So, it sounds like I was seduced by a couple of oddball websites. But I'm not clear on a couple of things. I think my underlying problem is a lack of understanding what ways programs "change" that are supposed to be absorbed and localized.

Say for instance you have a Model Person with two properties: Name, Address. If you pass this Model to the view, and the view has something like
code:
<li><?= $this->person->getName() ?></li>
Isn't that essentially the same as having the controller get the Name and pass it to a view variable? Only, if you want to display the Address too, now you have to modify both the controller and the view, whereas if you passed the view you just add another li $this->person->getAddress()?

In either case, It doesn't seem like changing the back-end storage media would need either to change.

Begby: Thanks for the warning about it sometimes being simpler to avoid framework implementations. As I mentioned before I think I am prone to doing things more complicated/awkwardly than they need to be.

I think I will have to try swapping framework as an exercise to understand. But, I'm still not sure how having the forms in there is a problem. I (think I) understand what you are saying about it being desirable for the model to stand alone, it's definitely something I was aiming for... but the Models only use the forms to validate data, so loading the Zend MVC stack isn't necessary to use them. What piece of the puzzle am I missing here?

I was definitely surprised by you guys' thoughts on the Controller. Is "fat model thin controller" a fringe philosophy after all? did I just misunderstand it? or is it just a matter of preference and not a rule?

KuruMonkey
Jul 23, 2004

sivo posted:

Say for instance you have a Model Person with two properties: Name, Address. If you pass this Model to the view, and the view has something like
code:
<li><?= $this->person->getName() ?></li>
Isn't that essentially the same as having the controller get the Name and pass it to a view variable? Only, if you want to display the Address too, now you have to modify both the controller and the view, whereas if you passed the view you just add another li $this->person->getAddress()?

Yes; because in the example you've given, its reasonable to assume you meant for the controller to have code along the lines of:

code:
$person = new PersonModel('david001'); // i.e. load one by id
$this->load->view('user_data', $person);
Note that the decision of which person is to be displayed is in the controller, how to load that data is in the model (the Person class) and how to display it is in the view. Thats it; that is MVC.

So storage change will only involve the model. Showing an extra field from the person is presentation, and is only going to involve the view. But changing which, how many and whether the person is displayed is behavious, and is a change to the controller.

Thats it; anyone who makes MVC seem more complex than that is also a moron. (and more importantly, doesn't understand what they're trying to explain to you)

Even if your situation involves handling a collection (of people, for example), this will still apply:

code:
// controller
$people = new UsersModel('select criteria here!'); 
// returns an array or otherwise iterable collection of User objects
$this->load->view('user_list', $people);
code:
// in the user_list view
foreach($people as $person)
{
// and output one record, nicely formatted
}
Its probably important to recognise from that example that I usually write models that do 2 things; interface to the storage, and package up and return objects and collections of objects that encapsulate what they loaded. Those objects get passed around the app, not the models. (models take in these types of object as the packages they use as data to write back to the DB.) More on this below.

Now, this is straying into in my opinion, but the essence of keeping your MVC separation clean, neat and consistent is to only pass collections that can be handled in full to the view.

So I would say that selection, sorting and pagination is the job of the MC section not the V section. That is; the controller decides what to select, how/if to sort and how/if to reduce the selection for pagination. The view then just formats and outputs what its told.

sivo posted:

I think I will have to try swapping framework as an exercise to understand. But, I'm still not sure how having the forms in there is a problem. I (think I) understand what you are saying about it being desirable for the model to stand alone, it's definitely something I was aiming for... but the Models only use the forms to validate data, so loading the Zend MVC stack isn't necessary to use them. What piece of the puzzle am I missing here?

I was definitely surprised by you guys' thoughts on the Controller. Is "fat model thin controller" a fringe philosophy after all? did I just misunderstand it? or is it just a matter of preference and not a rule?

If you try another framework I'd suggest Kohana or CodeIgniter in that order of preference. (CodeIgniter has bette docs though, I just prefer Kohanan now I've used both)

DEFINITELY have a test drive of at least one other framework, even just to look at/play with. It will let you evaluate how Zend actually is. (I've not used Zend)

I think to clarify the forms issue, I would follow this train of thought.

Conceptuall I think of a web based DB driven app (as a reasonable example to work on) as having a central PHP core. This handles data in 'PHP form', arrays, strings, objects etc.

Off one end, there's the web pages it generates. Making these involves a translation out of 'PHP form' and into 'html form'. The view handles that job, and as far as possible, ONLY the view.

Off the other end, there's the DB, and its not handling 'PHP form' either. The models handle that translation. And only the models.

SO; if you're considering something that is handling stuff thats not PHP data, its likely that either a model ora view is the right thing for the job. Conceptually, for me, the decision is a case of 'is it going towards the user, or towards PHP or the DB?' if towards the user, then a view. If towards PHP or the DB, then a model.

Forms are a lgitimately awkward case; I think in a perfect world (an in fact in my code) you have to split them up, mentally. You see a controller needs to know which form to use and when. A view has to render it for the user, but then I actually use a model to handle the acceptance of data from post/get, and the validation. (and somewhere in there, you need a record of what fields are in the form and what types they are for validation - this lets you generate and validate a form 'by id' if done right)

Handling forms well isn't simple, because they are 2-way, basically.

sivo
Dec 2, 2003
Life is but a dream
Thanks a bunch. I think I'm clicking on to it. I realized that in that post I confused passing the model with passing data as a package. I think the original point of confusion that started it all was how to deal with related child-type data, but the idea that the controller handles which and what while the view is passive clears this up.

Also thanks for the recommendation. I'll definitely look into Kohana.

walumachoncha
Jul 22, 2004
fraeulin doesn't like linux/GNOME :(
I have a bear of a form that I can't get to function correctly. I am helping setup a conference, and we have a php form that allows people to upload their powerpoint to us. The form was created using one of those "custom forms" websites, as no one here knows enough php to do it on our own.

The main problem seems to reside in the way that the form handles the uploaded powerpoint file; we would like it to enter the name of the uploaded file into our mysql database, just as all the other fields in the form, and to also save the powerpoint file itself in a designated folder in our server.

Right now all the fields populate the mysql database, except for the field that has the name of the file. the database table has the column for that field, but the entries are empty. Also, the way the form is setup, the only action performed with the uploaded file is to email it to a designated account, which is pretty impractical for obvious reasons.

Is there any way I could get help with this? I'm hesitant to paste the code here because of the copyright disclaimer in the code, but I can pm/email someone the php code.

walumachoncha fucked around with this message at 21:08 on May 4, 2009

indulgenthipster
Mar 16, 2004
Make that a pour over
Still getting used to Prepared Statements with MySQLi and have another question...

I can't figure out how to make another database call in the middle of this code to fetch more results:

php:
<?
    if (mysqli_stmt_prepare($stmt, $sql)) {
        mysqli_stmt_bind_param($stmt, 'i', $topid);
        mysqli_stmt_execute($stmt);
        mysqli_stmt_bind_result($stmt, $fieldid, $fieldtype, $parentid, $fieldvalue);
        while(mysqli_stmt_fetch($stmt)) {
        echo '<p>';    
        echo '<label for="'.$fieldid.'">'.$fieldvalue.'</label><br />';
            if($fieldtype == '1') {
                echo '<input type="text" />';
            } elseif($fieldtype == '2') {
                echo '<select>';
                                 //there needs to be another database call here to pull in the option values for the select
                               echo '</select>';
            } elseif($fieldtype == '3') {
                echo '<textarea></textarea>';
            }
        echo '</p>';    
        }
    }?>
With standard MySQL, I could just start another MySQL statement there. But now, what do I need to do?

Golbez
Oct 9, 2002

1 2 3!
If you want to take a shot at me get in line, line
1 2 3!
Baby, I've had all my shots and I'm fine

VerySolidSnake posted:

Still getting used to Prepared Statements with MySQLi and have another question...

I can't figure out how to make another database call in the middle of this code to fetch more results:

php:
<?
    if (mysqli_stmt_prepare($stmt, $sql)) {
        mysqli_stmt_bind_param($stmt, 'i', $topid);
        mysqli_stmt_execute($stmt);
        mysqli_stmt_bind_result($stmt, $fieldid, $fieldtype, $parentid, $fieldvalue);
        while(mysqli_stmt_fetch($stmt)) {
        echo '<p>';    
        echo '<label for="'.$fieldid.'">'.$fieldvalue.'</label><br />';
            if($fieldtype == '1') {
                echo '<input type="text" />';
            } elseif($fieldtype == '2') {
                echo '<select>';
                                 //there needs to be another database call here to pull in the option values for the select
                               echo '</select>';
            } elseif($fieldtype == '3') {
                echo '<textarea></textarea>';
            }
        echo '</p>';    
        }
    }?>
With standard MySQL, I could just start another MySQL statement there. But now, what do I need to do?

I'm a mysqli newbie myself, but wouldn't it work to just do the same code, but with a different stmt variable?

php:
<?
    if (mysqli_stmt_prepare($stmt, $sql)) {
        mysqli_stmt_bind_param($stmt, 'i', $topid);
        mysqli_stmt_execute($stmt);
        mysqli_stmt_bind_result($stmt, $fieldid, $fieldtype, $parentid, $fieldvalue);
        while(mysqli_stmt_fetch($stmt)) {
        echo '<p>';    
        echo '<label for="'.$fieldid.'">'.$fieldvalue.'</label><br />';
            if($fieldtype == '1') {
                echo '<input type="text" />';
            } elseif($fieldtype == '2') {
                echo '<select>';
                                $stmt2 = 'select * from whatever';
                                if (mysqli_stmt_prepare($stmt2, $sql)) {
                                  mysqli_stmt_bind_param($stmt2, $whatever);
                                  mysqli_stmt_execute($stmt2);
                                  mysqli_stmt_bind_result($stmt2, $stuff2);
                                  while (mysqli_stmt_fetch($stmt2)) echo $stuff2;
                                }
                               echo '</select>';
            } elseif($fieldtype == '3') {
                echo '<textarea></textarea>';
            }
        echo '</p>';    
        }
    }?>

Mug
Apr 26, 2005
How do you get cURL to handle sessions?

Using cURL to log into a website, the site seems to return some session data, how do I store that session data and send it again with all subsequent cURLs? Basically I use cURL to POST my username and password to a website, the website sends back a cookie and cURL stores it in the cookiejar. But the website sends back some session data, too. How do I store that?

My code below shows first I log into a website, storing the cookies in COOKIEFILE, then it tries to visit a page that only logged in users can see, using COOKIEJAR. But I get rejected, most likely due to not preserving the session data.

code:
<?php
	$cookiejar = "c:\\Inetpub\\wwwroot\\whmcs\\test-sys\\hats\\my_cookies.txt";
	$fp = fopen($cookiejar, 'w');
	fclose($fp);
	$url = "http://www.awebsite.com.au/online/toplogedIn.php";

	$postfields["username"] = "a user name";
	$postfields["passwd"] = "a password";

	$ch = curl_init();
	curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiejar);
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_TIMEOUT, 100);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
	$data = curl_exec($ch);
	echo(">>>". curl_error($ch) ."<<<");
	curl_close($ch);
	$pre_data = $data;
	echo("<!-- ". $data ." -->");
?>
LOGIN DONE... NOW
<?php
	$url = "http://www.awebsite.com.au/online/pricelist.php";
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiejar);
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_TIMEOUT, 100);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
	$data = curl_exec($ch);
	echo("<!-- ". $data ." -->");
	curl_close($ch);
?>

indulgenthipster
Mar 16, 2004
Make that a pour over

Golbez posted:

I'm a mysqli newbie myself, but wouldn't it work to just do the same code, but with a different stmt variable?

I believe that will not work, because from what I understand, you cannot start another prepared statement while another is running

Hanpan
Dec 5, 2004

I've having a hell of a time trying to get my head around working with basic hierarchical data. I am storing a list of "pages" in a mySQL database and as you'd expect each entry has a parent_id. I know there are better methods for doing this (pre-ordered traversal trees?) but since there is unlikely to be massive amounts of entries in this table, I'd like to keep it as simple as possible.

I'm trying to limit myself to using only one SQL query. I can't for the life of me figure out how to structure my array after I've retrieved the pages from the database.

Any suggestions / code would be really appreciated.

indulgenthipster
Mar 16, 2004
Make that a pour over
I think I have something to fix my prepared statements.

Lets say I have a query like this.

php:
<?
$sql = 'SELECT papers.papid AS papid, keywords.keyid AS keyid, keywords.keyword AS keyword
FROM papers,keywords
WHERE papers.topid = ?
AND keywords.topid = papers.topid';
    $stmt = mysqli_stmt_init($connect);
    
    if (mysqli_stmt_prepare($stmt, $sql)) {
        mysqli_stmt_bind_param($stmt, 'i', $topid);
        mysqli_stmt_execute($stmt);
        mysqli_stmt_bind_result($stmt, $papid, $keyid, $keyword);
        mysqli_stmt_fetch($stmt);
          //echo stuff here?
    }?>
I then can echo all these values, however, keywords only displays the first keyword it found (papid correctly displays one value). How do I make it display multiple keywords (that it should have found with this query)

indulgenthipster fucked around with this message at 22:13 on May 6, 2009

roxanne
Sep 5, 2006

I apologise in advance for the 'n00b'-ness of this question. I've googled but I'm still getting nowhere so you guys are kinda my last hope.:shobon:

php:
<?php

$dirPath '.';

if ($handle opendir($dirPath)) {

  while (false !== ($file readdir($handle))) {

      if ($file != "." && $file != "..") {
         if (is_dir("$dirPath/$file")) {
            echo "$file <br>";
         } 
      }
   }

   closedir($handle);
}

?>
I'm under the impression that this will list all directories within a directory. I'd like to change it so that it will not list any directoy named 'img'. I thought I should add $file != "img" but that was either wrong, or I put it in the wrong place, because it didn't work. Could anyone help?

EDIT - ooh. I think I did it. I added if (("$dirPath/$file") != "./img") and it seems to be working.

roxanne fucked around with this message at 00:04 on May 7, 2009

Acer Pilot
Feb 17, 2007
put the 'the' in therapist

:dukedog:

Whats a good way to encrypt and decrypt a variable with a specific salt?

KuruMonkey
Jul 23, 2004

roxanne posted:

EDIT - ooh. I think I did it. I added if (("$dirPath/$file") != "./img") and it seems to be working.


Thats only working because you've set $dirPath to '.' above; change that and your test is broken.

You should be able to use if($file != 'img') and it should work

You could restructure your code a bit to make this simpler to modify/extend:

php:
<?
// use a portable separator, shorten it for convenience
define('DS', 'DIRECTORY_SEPARATOR');

$dirPath = '.';
$rejects = array('.', '..', 'img'); // and any others...

if($handle = opendir($dirPath))
{
  while(false !== ($file = readdir($handle))) 
  {
    // put the test most likely to fail first
    if(is_dir($dirPath.DS.$file) && !in_array($file, $rejects)) 
    {
      echo $file.'<br>';
    } 
  }
  closedir($handle);
}
?>

Begby
Apr 7, 2005

Light saber? Check. Black boots? Check. Codpiece? Check. He's more machine than kid now.

drcru posted:

Whats a good way to encrypt and decrypt a variable with a specific salt?

What exactly are you trying to accomplish? Do you want to encrypt some text and store it and decode it with a password or keyphrase later? Or are you trying to encrypt a password for storing in a db? something else?

Acer Pilot
Feb 17, 2007
put the 'the' in therapist

:dukedog:

Begby posted:

Do you want to encrypt some text and store it and decode it with a password or keyphrase later? Or are you trying to encrypt a password for storing in a db?

This. I want to be able to encrypt and store in the DB and later decrypt it. Any easy ways of doing this?

supster
Sep 26, 2003

I'M TOO FUCKING STUPID
TO READ A SIMPLE GRAPH

drcru posted:

This. I want to be able to encrypt and store in the DB and later decrypt it. Any easy ways of doing this?

You want to look into mcrypt.

nbv4
Aug 21, 2002

by Duchess Gummybuns
I am having a hard time figuring out character encodings. I have a function that crawls a webpage that happens to be encoded in ISO-8859-1. Some text is lifted off that site and then ran through utf_encode() and then stored in a database. When I view the contents of that field in phpMyAdmin, it looks like this: "México", with a "A" with a squiggly line above it and a copyright logo instead of an "e" with an accent mark as how it looks on the original ISO-8859-1 page. The phpMyAdmin page is encoded in UTF-8, so I don't know what is happening. Is this caused by utf_encode() not working? What could be causing this?

The "collation" of the databse is "latin1_swedish_ci", could that be the problem? I think I remember messing with encoding a few months ago, and changing the collation didn't change anything. When I drawl the info from the database it works fine, with the accent mark displaying correctly, which gets me because the page I use to display the data is set to UTF-8 as well...

Standish
May 21, 2001

nbv4 posted:

it looks like this: "México", with a "A" with a squiggly line above it and a copyright logo
That is the correct UTF-8 encoding of the "e grave" character "0xC3 0xA9", except your browser is interpreting it as ISO-8859-1 where 0xC3="A tilde" and 0xA9="copyright symbol".

Looks like utf8_encode is working fine, check your page charset.

Alex007
Jul 8, 2004

I have a similar problem... One of my PHP scripts receives a tab separated file from FileMaker on a Mac.

I read the file with file_get_content(), then explode() it on "\r" to get records, and then I explode() these on "\t" to get the fields. That part is working fine.

The problem is that I have no idea what the encoding is on that file. When I look at the data, all accented characters are wrong. Where I expect to see an "ê" (that's E-circ) I see a blank space. I checked the ascii value for that space and it's 143.

mb_convert_encoding() seems to say the encoding is "ISO-8859-1", so I try to convert it to UTF-8 using:

code:
$Line = mb_convert_encoding($Line, 'UTF-8', 'ISO-8859-1');
And this seems to help, because now the "ê" is not two chars, 194 and 143, which seems to be the character I want. But when I insert this in the DB, the screen that displays it IS UTF-8, but displays it wrong. It gets displayed as "Â?".

What am I doing wrong ?

Lamb-Blaster 4000
Sep 20, 2007

Im working on a site hosted at a server running mysql 4, my dev machine's php has mysql 5 and when I attempt to connect to the remote server I get

Unknown MySQL server host '<the server>' (11004)

the same when I try to shell in.

is there an easy way to tell my dev php to use the mysql4 driver? and also is there a way to do the same when I use the shell?

supster
Sep 26, 2003

I'M TOO FUCKING STUPID
TO READ A SIMPLE GRAPH
Does anyone have any experience with reliable ways of stripping out Javascript and any malicious HTML (e.g., iframes) out of user-submitted HTML?

Lamb-Blaster 4000
Sep 20, 2007

a lot of existing php driven sites like phpbb, wordpress etc have tried and true stuff.

preg_replace() is one of your best options, write a regex for stuff like <script>.*?</script> etc

worst case scenario, pick apart wordpress's comment filtering algorithms, or look into akismet?

Supervillin
Feb 6, 2005

Pillbug

supster posted:

Does anyone have any experience with reliable ways of stripping out Javascript and any malicious HTML (e.g., iframes) out of user-submitted HTML?

To build on LB4's answer:

php:
<?
    $input = '<script type="text/javascript">alert("hacked!");</script>';
    $magic = '#<(script|iframe).*?>(.*?)</\\1>#i';
    $output = preg_replace($magic, '\\2', $input);
    echo $output; // safe, plain text: alert("hacked");
?>
Or if you want to strip the contents AND the tag, replace the '\\2' with just '' (or "I'm a dumb hacker" or whatever).

Edit: vvv This is not a catchall, nor was it supposed to be. As mentioned, if you want to catch everything, catch EVERYTHING and write up a bbcode-style parser. No blacklist, no whitelist, there will be ways around both. filter_var($input, FILTER_SANITIZE_STRING) is my favorite.

Supervillin fucked around with this message at 16:14 on May 13, 2009

supster
Sep 26, 2003

I'M TOO FUCKING STUPID
TO READ A SIMPLE GRAPH
There's now way you can trust a simple regular expression like that to catch everything. What about <a href="java script:_____">, what about DOM element event handlers (e.g., onclick, onmouseover, etc). There's a ton of ways to obfuscate malicious javascript/html so that naive parsers (such as a simple regex) don't catch them.

Wordpress does not do any sort of filtering, you are free to post whatever you want on your blog. Comments are plain text only (right? I think so at least, I will look into it).

phpBB and other forums do not allow direct HTML input and resort to BBCode or other forms of input such as textile or markup. Their filtering will first parse ALL html out of the post and then parse the BBCode/textile/markup/etc into safe predefined html. It is trivial to filter out ALL html/javascript, but it is not so simple to filter out only potentially malicious html/javascript.


edit: I found http://htmlpurifier.org/ which looks promising.
edit2: and http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/index.php which seems like a more light weight alternative.

supster fucked around with this message at 04:00 on May 13, 2009

Lamb-Blaster 4000
Sep 20, 2007

ours were just examples of using regex, obviously you're gonna want to use as many patterns as you want or need. Maybe you're best off doing like phpbb and removing all but the basic styling tags and further removing any handlers? As well as scrubbing out script tags completely?

edit: that DOES look promising! *bookmarks*

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
A (very restrictive) whitelist is the only remotely sane and safe way to do it. Pick a set of safe tags, safe attributes for those tags, and safe protocols for urls and strip everything else. If you have any doubt about if something is safe, don't include it in the whitelist.

Begby
Apr 7, 2005

Light saber? Check. Black boots? Check. Codpiece? Check. He's more machine than kid now.

Lamb-Blaster 4000 posted:

Im working on a site hosted at a server running mysql 4, my dev machine's php has mysql 5 and when I attempt to connect to the remote server I get

Unknown MySQL server host '<the server>' (11004)

the same when I try to shell in.

is there an easy way to tell my dev php to use the mysql4 driver? and also is there a way to do the same when I use the shell?

This error does not have to do with mysql versions, but rather there is a problem connecting to the remote mysql machine. Either you are using an invalid IP address, or there is a DNS issue where the name is not resolving correctly, or its trying to connect over a proxy or something.

Begby
Apr 7, 2005

Light saber? Check. Black boots? Check. Codpiece? Check. He's more machine than kid now.
This is interesting

http://bugs.php.net/bug.php?id=48139

MononcQc
May 29, 2007

Begby posted:

This is interesting

http://bugs.php.net/bug.php?id=48139

How much of a moron do you have to be not to be able to use PHP with MySQL on windows?
Install any WAMP stack and you're good to go. The guy is on windows and there are plenty of stacks available; I can't even comprehend how he can't get it to load dlls when it should be done without touching the config.

Goon in the Mist
Jan 6, 2006

I want a script that will return a random picture from Flickr by tag, above a certain resolution, which I can then resize to 1024*768 using image magic. ex: Tag specified is "stairs," script returns a 2048*1024 picture of a staircase. On refresh, it returns a different one.

Is this easily accomplished by someone who is a php retard? (i've basically used it to make forms, nothing more complicated than that.)

Lamb-Blaster 4000
Sep 20, 2007

not only do you need to know the gd and exif libraries, but you'll need some knowledge of the Flickr API (and an API key- both of which are easily attained at flickr)

There may be a flickr class floating around on the net already

http://phpflickr.com/ (first result googling for "php flickr class")

hey look at that! Anyways, now you just need to do the gd, which is pretty basic, php.net will tell you all about the functions you need

look around for imagecreatefromjpeg, imagejpeg, imagecopyresampled and imagecreatetruecolor

or google around for an image class (http://code.google.com/p/php-image/wiki/PHPImage) was my first result

Lamb-Blaster 4000
Sep 20, 2007

sorry to double post, it's been 10 hours since the above post and this is a different issue:

what's the deal with the difference between include paths in php4 and php5 and how can I make include work in both versions?

As noted before, my dev machine is php5 and the production machine is php4

KuruMonkey
Jul 23, 2004
Describe in more detail the setup on you dev machine; is it a wamp variant? Windows? Unix? Running on your machine / under your control? Shared with others / for you own personal dev work?

(knowingly having the dev machine run a newer version of php than you will deploy on is STUPID; I deem to recall its your boss who made this clever decision?)

If your include paths are troublesome the problem is most likely not the difference between php4 and php5 (as so far as I know there is no difference between them in this regard).

It is more likely a difference in the setup of php on the 2 machines. (e.g. is one unix and the other windows?, does one have the include path setup and the other not etc)

write yourself the usual phpinfo.php file, and run that on both machines; compare the settings, looking for path differences. (and I'm talking about one machine having you tied down to only certain include paths, although excluding '.' from that would be a case of misconfiguration)

And be sure you are specifying paths cross-platformly, and in a manner that allows you to move the files without re-editing e.g. a start is to do:

php:
<?
define('MYPATH', dirname(realpath(__FILE__)));
include(MYPATH.DIRECTORY_SEPARATOR.'does_this_work_on_both.php');
// assumes the included file is in the same dir
?>

KuruMonkey fucked around with this message at 08:23 on May 14, 2009

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
Got this email the other day:

quote:

Dear Philip,

With a couple of my friends we play [game] on your site. However, since we play from Turkey we experience some problems when connecting to your site. Thus we wanted to talk to you about mirroring your site in Turkey. Or we could also translate it to Turkish for gaining more players. Giving you and [the game's creator] all the credit we can host the site in Turkey.

Best regards,

[name removed]

For obvious reasons I have no intention of giving this guy the PHP scripts that make up my website. But I am not averse to adding the functionality to my site that would allow it to be displayed in different languages (translated by users). I'm just not sure how I'd go about it.

One idea: replace all "echo" statements with calls to "multiecho" where multiecho is defined in a central configuration file as follows:

php:
<?
function multiecho ($english, $turkish = '') {
    global $user_language;
    switch ( $user_language ) {
        case 'turkish': echo $turkish; break;
                        // where 'turkish' would more likely
                        // be a numerical code I guess
        default: echo $english; break;
    }
}?>
So then I just go through replacing most of my echo statements with these; so
php:
<?
echo 'Please enter your password.';

// becomes

multiecho('Please enter your password.',
          'Lütfen &#351;ifrenizi giriniz.'
);?>
Disadvantages: Aside from the fact that I'll need to go through replacing all the echos that need replacing, which would be the case in any solution to this problem, I would need to do pretty much the same thing again if I ever get offers to translate into a third, fourth etc. language.

Second option: Associate to each public-accessible script a file containing the text that might be required for that file. So for login.php, we might have a file either inside or outside of webroot called "login_text.php" (say) that looks something like

php:
<?
$text=array(
'enter-name'=>array('Please enter your login name.',
                    'Lütfen giri&#351; ad&#305; girin.'),
'enter-password'=>array('Please enter your password.',
                        'Lütfen &#351;ifrenizi giriniz.'),
'click-submit'=>array('When you are done, click the "submit" button.',
                      'the turkish is long and breaks tables')
);?>
And then I can replace echo statements with

php:
<?
echo $text['enter-password'][$user_language];?>
Disadvantages: seems like it might add a certain amount of overhead for the web server? But perhaps not significantly more than the first option. I don't really know.

Third option: As with the second option, but with a file for each language as well as for each script, and include statements that look something like

php:
<?
include 'path/login_text_'.$user_language.'.php';?>
(Seems rather cumbersome files-wise)

Additional question: the email guy says he and his friends "experience some problems when connecting to" my site. What kind of problems is he likely to be talking about? Do they just have unreliable internet access over there?

Acer Pilot
Feb 17, 2007
put the 'the' in therapist

:dukedog:

They probably have terrible pings since you're likely somewhere in North America and they're XX hours away by plane.

Adbot
ADBOT LOVES YOU

moops
Jul 16, 2001

it's a typo

Hammerite posted:

i10n & i18n stuff

Turkey is one of the hardest countries to localize, if there is a standard way of doing something they do the opposite (I believe this might be just out of spite.. but I'm not sure)

http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html

Don't reinvent the wheel.. Use gettext
http://php.net/gettext

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