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
Sneaking Mission
Nov 11, 2008

php:
<?
$flv_str='abc[flv]def[/flv]ghi';

preg_match('|\[flv\](.*)\[/flv\]|', $flv_str, $matches);
print_r($matches);
?>

Array
(
[0] => [flv]def[/flv]
[1] => def
)



The square brackets ("[" and "]") define a character class to match when you are dealing with regular expressions. Escaping them with the backslash forces them to only match actual brackets in the string and not evaluated as special characters. You can use parentheses to define groups of characters to match which PHP will copy into the matches array.

Sneaking Mission fucked around with this message at 05:15 on Feb 13, 2010

Adbot
ADBOT LOVES YOU

Sebbe
Feb 29, 2004

Sneaking Mission posted:

php:
<?
$flv_str='abc[flv]def[/flv]ghi';

preg_match('|\[flv\](.*)\[/flv\]|', $flv_str, $matches);
print_r($matches);
?>

Array
(
[0] => [flv]def[/flv]
[1] => def
)


Mind you, if the text contains the tag multiple times, it'll go afoul:
php:
<?
$flv_str='abc[flv]def[/flv]ghi[flv]jkl[/flv]mno';

preg_match('|\[flv\](.*)\[/flv\]|', $flv_str, $matches);
print_r($matches);
?>
gives:
code:
Array
(
    [0] => [flv]def[/flv]ghi[flv]jkl[/flv]
    [1] => def[/flv]ghi[flv]jkl
)
For that scenario, you'll want a frugal match, like so:
php:
<?
preg_match_all('|\[flv\](.*?)\[/flv\]|', $flv_str, $matches);
?>

Fruit Smoothies
Mar 28, 2004

The bat with a ZING
I just hope you don't need any of these to be recursive...

the chip
Mar 10, 2002

Fun Shoe
php:
<?php

Class Actor
{
    var $name;
    var $health;
    var $str;
    var $dex;
    var $attack;
    var $position=array('x'=>1,'y'=>1);
    
    function Attack($target)
    {
        echo $this->name " attacks " $target->name " with " $this->attack ". <br />";
        echo $this->name ." inflicts " $this->str " points of damage.";
        $target->health-= $this->str;
        echo $target->name "now has " $target->health " health points.";
    }
}

$squid=new Actor();
$squid->name='Angry Squid';
$squid->health="20";
$squid->str="4";
$squid->dex="5";
$squid->attack="Tentacle Attack";
$squid->position=array('x'=>3,'y'=>1);

$octo=new Actor();
$octo->name="Horny Octopus";
$octo->health='30';
$octo->str='2';
$octo->dex="5";
$octo->attack="8 Armed Crusher";
$octo->position=array('x'=>2,'y'=>1);
?>

<form action="ootest2.php" method="post">
Enter the instance names below (eg. $squid, $octo)<br />
Attacker: <input type="text" name="actor1" /><br />
Defender:<input type="text" name="actor2" /><br />
<input type="submit" />
</form> 
In another file:
php:
<?php
require "ootesting.php";
$actor1=$_POST["actor1"];
$actor2=$_POST["actor2"];

//This is where I need to use the value in $actor1 and 2 to call the fight method in class.

?>

I may be totally barking up the wrong tree here but I am trying to call
$actor1->Attack($actor2);

Which spits out an expected error. How can I go about actually doing this?

DoctorScurvy
Nov 11, 2005
More of a passing curiosity, really

Dargor posted:

I may be totally barking up the wrong tree here but I am trying to call
$actor1->Attack($actor2);

Which spits out an expected error. How can I go about actually doing this?
Your problem is that $actor1 and $actor2 are only going to be strings like "$squid" and "$octo". Here, I played around and this is working for me (all one file):
php:
<?php

Class Actor
{
    var $name;
    var $health;
    var $str;
    var $dex;
    var $attack;
    var $position=array('x'=>1,'y'=>1);
    
    // This is a constructor function which is a neater way to set up a new actor
    // $actor = new Actor(name, health, strength, dexterity, attack, position array);
    function Actor($name$health$str$dex$attackname$position) {
        $this->name $name;
        $this->health $health;
        $this->str $str;
        $this->dex $dex;
        $this->attack $attackname;
        $this->position $position;
    }
    
    function Attack($target) {
        echo $this->name " attacks " $target->name " with " $this->attack ". <br />";
        echo $this->name ." inflicts " $this->str " points of damage. <br />";
        $target->health-= $this->str;
        echo $target->name "now has " $target->health " health points.";
    }
}

// an array of actors lets you pick out the ones you want by using their names
$actorlist = array(
    'squid'=>new Actor('Angry Squid'2045'Tentacle Attack', array('x'=>3,'y'=>1)),
    'octo'=>new Actor('Horny Octopus'3025'8 Armed Crusher', array('x'=>2'y'=>1))
);

// these are simple strings like 'squid' or 'octo'
$postactor1 $_POST['actor1'];
$postactor2 $_POST['actor2'];

// if the actor name is found in the actorlist, then $actor1 becomes a copy of it
$actor1 = (isset($actorlist[$postactor1])) ? $actorlist[$postactor1] : 'NULL';
$actor2 = (isset($actorlist[$postactor2])) ? $actorlist[$postactor2] : 'NULL'// ditto

// only do the attack if both actors were found in the list
if ($actor1 != 'NULL' && $actor2 != "NULL") {
    $actor1->Attack($actor2);
}

?>

<form action="ootest.php" method="post">
Select <br>
Attacker: <select name='actor1'><option><? echo join('</option><option>', array_keys($actorlist)); ?></option></select><br>
Defender: <select name='actor2'><option><? echo join('</option><option>', array_keys($actorlist)); ?></option></select><br>
<input type="submit" />
</form> 
Of course you'll have to change things around to suit how you actually intend it to be used but you can see that the form can only send the name of the actor but that is not automatically assigned to any actual Actor object. You could go ahead and only have the script generate the actors required from a database, etc.

DoctorScurvy fucked around with this message at 07:34 on Feb 14, 2010

Fluue
Jan 2, 2008
I'm trying to setup a tournament system but I can't seem to figure out how to generate brackets.

Right now I have the system setup so that users can join and create tournaments. What I would like to do is have the system create a bracket (the seeds/first round should match up users randomly) and then allow the users to click a button at the end of their match to say that they won or lost to move to the next round.



This is what I'm hoping to have a final result.

How would I go about setting up the system like this? I already have a MySQL table that holds the entries for each tournament, but would this involve making another table that would hold placement data?

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Fluue posted:

I'm trying to setup a tournament system but I can't seem to figure out how to generate brackets.

Right now I have the system setup so that users can join and create tournaments. What I would like to do is have the system create a bracket (the seeds/first round should match up users randomly) and then allow the users to click a button at the end of their match to say that they won or lost to move to the next round.



This is what I'm hoping to have a final result.

How would I go about setting up the system like this? I already have a MySQL table that holds the entries for each tournament, but would this involve making another table that would hold placement data?

Yup. At the minimum, you'll need a match table that stores the tournament ID, what round of the tourney it is, the IDs of the two teams playing, a match ID, and a result field.

Fluue
Jan 2, 2008

Lumpy posted:

Yup. At the minimum, you'll need a match table that stores the tournament ID, what round of the tourney it is, the IDs of the two teams playing, a match ID, and a result field.

Alright, thanks!

I still can't figure out how to randomly match users up to populate the two player fields for each match row. Would it be a matter of rand() and then checking every time it's run to see if the user is already matched up?

On a side note, I'm trying to figure out where I'm going wrong with this code. I'm trying to get populated data from a MySQL database to appear in an input box, but without slashes. I tried stripslashes, which truncated the data. Then I used htmlentities() to fill the form, which worked. However, when I resubmitted the data back into the database it added more slashes. So I used stripcslashes() on the updated string before doing mysql_real_escape_string to the posted data. Now it submits data without any slashes into the database, despite what var_dump() says. Am I creating a massive security exploit?

Sebbe
Feb 29, 2004

Fluue posted:

I still can't figure out how to randomly match users up to populate the two player fields for each match row. Would it be a matter of rand() and then checking every time it's run to see if the user is already matched up?

Shuffle the list, take out two at a time?

Hammerite
Mar 9, 2007

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

Sebbe posted:

Shuffle the list, take out two at a time?

Here's code that does this:

I presuppose that $entrants is an array containing identifiers (ID numbers, usernames, whatever) of the people who are going to play in the tournament. Sensibly it should have an even number of entries, but I don't assume this.

code:
shuffle($entrants);
$pairings = array();
while ( count($entrants) > 1 ) {
    $pairings[] = array(array_pop($entrants),array_pop($entrants));
}
Now $pairings is an array of randomly-chosen pairs of users. The entries are all themselves arrays having two elements each. So the first pair is $pairings[0][0] and $pairings[0][1], the second pair is $pairings[1][0] and $pairings[1][1], and so on.

the chip
Mar 10, 2002

Fun Shoe
Thanks DoctorScurvy! Worked like a charm. :hfive:

josh04
Oct 19, 2008


"THE FLASH IS THE REASON
TO RACE TO THE THEATRES"

This title contains sponsored content.

Fluue posted:

On a side note, I'm trying to figure out where I'm going wrong with this code. I'm trying to get populated data from a MySQL database to appear in an input box, but without slashes. I tried stripslashes, which truncated the data. Then I used htmlentities() to fill the form, which worked. However, when I resubmitted the data back into the database it added more slashes. So I used stripcslashes() on the updated string before doing mysql_real_escape_string to the posted data. Now it submits data without any slashes into the database, despite what var_dump() says. Am I creating a massive security exploit?

When you're viewing the data in the database, or when you've just gotten it out from the database, it's not supposed to have slashes on. You put the slashes on before it goes into the database so mySQL can tell what is the text you're entering and what is the query itself. mySQL will remove the slashes once it knows what you want it to do.

There's no need to be using stripslashes at all, unless you have magic_quotes on, in which case use stripslashes then use mysql_real_escape_string.

Hammerite
Mar 9, 2007

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

josh04 posted:

When you're viewing the data in the database, or when you've just gotten it out from the database, it's not supposed to have slashes on. You put the slashes on before it goes into the database so mySQL can tell what is the text you're entering and what is the query itself. mySQL will remove the slashes once it knows what you want it to do.

There's no need to be using stripslashes at all, unless you have magic_quotes on, in which case use stripslashes then use mysql_real_escape_string.
If magic_quotes_runtime is on (not common) then data obtained from database queries may have extraneous slashes as well. More likely is that the data is double-escaped though (e.g. because magic_quotes_gpc is on and a script is escaping the data as well).

Run this code and tell us what it outputs

code:
if ( get_magic_quotes_gpc() ) { echo 'magic_quotes_gpc is on'; }
else                          { echo 'magic_quotes_gpc is off'; }
echo '<br><br>';
if ( get_magic_quotes_runtime() ) { echo 'magic_quotes_runtime is on'; }
else                              { echo 'magic_quotes_runtime is off'; }

Fluue
Jan 2, 2008
Yeah, I believe I might be double-escaping the data since this is what I got as output from Hammerite's code:

code:
magic_quotes_gpc is on

magic_quotes_runtime is off

Hammerite
Mar 9, 2007

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

Fluue posted:

Yeah, I believe I might be double-escaping the data since this is what I got as output from Hammerite's code:

code:
magic_quotes_gpc is on

magic_quotes_runtime is off

Well, do you know where in your code escaping of user-supplied data occurs? Depending on how you implement it, it could be as simple as changing something like
code:
$newvariable = mysqli_real_escape_string($link,$_POST['oldvariable']);
so that it says instead
code:
$newvariable = $_POST['oldvariable'];
if ( get_magic_quotes_gpc() ) { $newvariable = stripslashes($newvariable); }
$newvariable = mysqli_real_escape_string($link,$newvariable);
The stripslashes part is the crucial part.

Alternatively, if you have access to php.ini you can change it there (but I like just testing for magic_quotes and responding appropriately, because it makes code portable)

Hav
Dec 11, 2009

Fun Shoe

eHacked posted:

I'm trying to search a long string to find a certain tag:

[flv]blahblahblkahblah[/flv]

Just be aware that perl reg expression under PHP are slow compared with matching and snipping strings (using strpos and substr).

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

Hammerite posted:

Well, do you know where in your code escaping of user-supplied data occurs? Depending on how you implement it, it could be as simple as changing something like
code:
$newvariable = mysqli_real_escape_string($link,$_POST['oldvariable']);
so that it says instead
code:
$newvariable = $_POST['oldvariable'];
if ( get_magic_quotes_gpc() ) { $newvariable = stripslashes($newvariable); }
$newvariable = mysqli_real_escape_string($link,$newvariable);
The stripslashes part is the crucial part.

Alternatively, if you have access to php.ini you can change it there (but I like just testing for magic_quotes and responding appropriately, because it makes code portable)

Just use PDO and prepared statements and you dont have to deal with any of this bullshit

KarmaticStylee
Apr 21, 2007

Aaaaaughibbrgubugbugrguburgle!
Are any of you familiar with Kohana 3? Would love to get a brief review

epswing
Nov 4, 2003

Soiled Meat
I've used Kohana 2.3.4 for almost a year now. 2.4 is code complete, they're still working on documentation, but I plan to upgrade to that when it's released. I moved from CodeIgniter to Kohana and have mostly enjoyed (as much as one can enjoy PHP web development) the experience.

Kohana 3, although many concepts are the same, is a rewrite. I'm also interested in a review.

cka
May 3, 2004
Kohanas 2 and 3 are in theory identical (as good as PHP frameworks can get), and apparently perform the same, the deciding factor probably boils down to whichever style you like programming in -- HMVC (3) or regular MVC (2). 2 has a leg up in that it already has familiarity, a stable codebase and a poo poo-ton of docs, but 3 has new enhanced features like $this->request to handle the request flow, a 150% better/more powerful routing system, easy sub-request controller calls in controller methods to make code more portable, FAR better ORM plugins, etc. 3 kind of sucks in that they stripped out a ton of the random functionality from 2 and modularized it, but I can understand where they're coming from there.

If you're looking for opinions, I'd say stick with 2 until 3 matures some more and gets some half-way decent documentation out (as nice as the wiki on kerkness.ca and cheat-sheet sites are, they're still no real replacement for developer-written, example-based documentation.) The only lovely part is that you'd have to rewrite your sites almost from the ground up when you did upgrade to Kohana 3; something I truly don't wanna do but probably have to do at some point...

Quick & dirty examples of Kohana controllers to show differences:

php:
<?php
// classes/controller/kohana3.php
class Controller_Kohana3 extends Controller 
{
  public function before() 
  {
    // Kohana 3's version of controller::__construct()
    // good for setting up controller specific variables and initializing
    // database connections if required
    parent::before();
  }

  public function action_index() 
  {
    // $this->request is the lifeblood of your Kohana 3 app, as it 
    // handles all of the information you want to display through the request flow
    $this->request->response "honk";
  }
  public function after() 
  {
    // post-request code runs here, this functionality is handled by 
    // binding an event trigger in kohana 2
    parent::after();
  }

}

// controller/kohana2.php
class Kohana2_Controller extends Controller 
{
  public function __construct() 
  {
    // constructor to set any controller-wide variables or do any controller-wide code
    parent::__construct();
    // bind a post-controller event to mimic kohana 3's controller::after() behaviour
    Event::add('system.post_controller', array($this'__postrequest'));
  }
  public function index() 
  {
    // since there's no $this->request to handle the request flow, 
    // Kohana 2 outputs controller method data directly
    echo "honk";
  }

  public function __postrequest() 
  {
    // this functionality is not native to Kohana 2, 
    // but we can bind it with the event trigger functionality
    // great for doing stuff like GC, session updating, or statistics tracking
  }
}

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I visited my site this evening and found that it had been replaced with a standard "no content uploaded yet" page with the branding of the hosting provider. So I went to check my emails to check on whether there was anything explaining this behaviour, and found the following, sent about 26 hours ago:

Email posted:

Dear [my name],

Your site uses too much of the servers resources which is having a negative impact on other users. On average in the last 24 hours your site used over 35% of the available CPU and 20% of the available Memory. You are allowed to exceed 25% usage for no more than 90 seconds.  To put this in perspective, your site is the #1 highest resource user of all sites hosted on SERVER3. I don't believe it is a bandwidth issue because there are other sites on the server that use far less resources and have 10 times the bandwidth usage.

...

I didn't have any idea my site was using inordinately many resources. How is a situation like this tackled? I have no idea whether altering my site to use fewer resources would be easy or difficult, and besides that I have no idea what I would need to do or where to start.

I do not know what to search for on the internet, since searching for terms like "memory use" or "cpu quota" gives results that are either about monitoring resource use on PCs, or are complaints (but no technical advice) from people who have run into similar problems.

Upgrading to a VPS solution is not realistic; it would cost more in a month than I had been signed up to pay in a year.

edit: site is a PHP/MySQL web application, not remarkable in any way that I can think of.

Supervillin
Feb 6, 2005

Pillbug

Hammerite posted:

CPU

CPU issues usually come from a loop that's running too long, and depending on what's in your database and how you are accessing it, even a basic PHP/MySQL app could spin long enough to cause problems.

If you have a loop that you know is running through a ton of results, consider putting a usleep(500) inside it. That will pause for 1/20th of a second each run through the loop. The tradeoff is additional execution time, but it will bring CPU usage down a lot.

What else is your code actually doing? There are many ways to optimize your code, if you're not sure whether you're using best practices for performance, you might consider posting code examples for us to look at.

McGlockenshire
Dec 16, 2005

GOLLOCKS!

quote:

Upgrading to a VPS solution is not realistic; it would cost more in a month than I had been signed up to pay in a year.
You get what you pay for. That cheap $5 a month hosting plan is shared with probably a few hundred other sites, just to keep the server profitable.

VPSes aren't expensive, most quality VPS hosts have plans starting at about $20/month.

Hammerite
Mar 9, 2007

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

Supervillin posted:

CPU issues usually come from a loop that's running too long, and depending on what's in your database and how you are accessing it, even a basic PHP/MySQL app could spin long enough to cause problems.

What else is your code actually doing? There are many ways to optimize your code, if you're not sure whether you're using best practices for performance, you might consider posting code examples for us to look at.

This is interesting information, because just today I have been working on decreasing the amount of information shown on the front page of my site. Up until this point my site has displayed a big ol' table on the front page that lists all of the games that are currently "in progress". That was ok when it was a bit smaller, but now there are 300 games going on that table is really big and I suspect a large part of my bandwidth was going into serving people my front page. So I was working today on having it just show 25 games on the front page instead of all 300.

I wonder whether this change would go a significant way towards reducing resource use as well, then.

Hammerite
Mar 9, 2007

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

Supervillin posted:

CPU issues usually come from a loop that's running too long, and depending on what's in your database and how you are accessing it, even a basic PHP/MySQL app could spin long enough to cause problems.

It occurred to me that all of my pages fetch at least a little text data from the database - I have various text passages stored in the database for i18n purposes. And when I say that, I mean that depending on the page, up to about 100 different text passages might be fetched from the database (in whatever is the language the user has selected as his preferred language), and then prepared by being placed in an array. Could this be impacting my resource use significantly?

Supervillin
Feb 6, 2005

Pillbug

Hammerite posted:

It occurred to me that all of my pages fetch at least a little text data from the database - I have various text passages stored in the database for i18n purposes. And when I say that, I mean that depending on the page, up to about 100 different text passages might be fetched from the database (in whatever is the language the user has selected as his preferred language), and then prepared by being placed in an array. Could this be impacting my resource use significantly?

Without seeing all the relevant code, all I can say is "could be". How often do the 100 fetched passages change? If you can cache the results for a minute, 10 minutes, an hour, a day, whatever makes sense for your data, then while it's cached you get a one-step file fetch instead of a hundred-step database loop.

code:
    $maxage = 10; // minutes
    $cache = 'some-meaningful-filename.txt';
    clearstatcache();
    $output = '';
    if (!file_exists($cache) || filemtime($cache) < (time() - (60 * 60 * $maxage))) {
        // need to refresh the cache
        $q = "SELECT crap FROM table WHERE stuff happens";
        $r = mysql_query($q, $db);
        while ($row = mysql_fetch_assoc($r) {
            $output .= '<li>' . $row['whatever'] . '</li>';
        }
        file_put_contents($cache, $output);
    }
    $output = file_get_contents($cache);

    echo '<ul>' . $output . '</li>'; // or whatever you want to do with it
That will cause the CPU spike only when the cache doesn't exist or when it is no longer fresh. If it's a really lovely query you may still need to sleep inside the loop, but if 100 rows is hitting your host's CPU for longer than 90 seconds then you just need to switch hosts.

KarmaticStylee
Apr 21, 2007

Aaaaaughibbrgubugbugrguburgle!
Thanks for the Kohana overview! I have a question about one more framework (want to get away from CodeIgniter for a big project I have)

Who can tell me about Yii?

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

Supervillin posted:

Without seeing all the relevant code, all I can say is "could be". How often do the 100 fetched passages change? If you can cache the results for a minute, 10 minutes, an hour, a day, whatever makes sense for your data, then while it's cached you get a one-step file fetch instead of a hundred-step database loop.

php:
<?
    $maxage = 10; // minutes
    $cache = 'some-meaningful-filename.txt';
    clearstatcache();
    $output = '';
    if (!file_exists($cache) || filemtime($cache) < (time() - (60 * 60 * $maxage))) {
        // need to refresh the cache
        $q = "SELECT crap FROM table WHERE stuff happens";
        $r = mysql_query($q, $db);
        while ($row = mysql_fetch_assoc($r) {
            $output .= '<li>' . $row['whatever'] . '</li>';
        }
        file_put_contents($cache, $output);
    }
    $output = file_get_contents($cache);

    echo '<ul>' . $output . '</li>'; // or whatever you want to do with it
?>
That will cause the CPU spike only when the cache doesn't exist or when it is no longer fresh. If it's a really lovely query you may still need to sleep inside the loop, but if 100 rows is hitting your host's CPU for longer than 90 seconds then you just need to switch hosts.

Or you could do:

php:
<?
function getData() {
    $memcache = new Memcache();
    $memcache->connect('memcache_host', 11211);

    $data = $memcache->get('key');
    if (data == null) {
        $data = getDataFromDatabase();
        $memcache->add('key', $data, false, 30);
    }
    return $data;
}
?>

Hammerite
Mar 9, 2007

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

Supervillin posted:

Without seeing all the relevant code, all I can say is "could be". How often do the 100 fetched passages change? If you can cache the results for a minute, 10 minutes, an hour, a day, whatever makes sense for your data, then while it's cached you get a one-step file fetch instead of a hundred-step database loop

I have not used caching of results before. I will look into it, since by the sound of it it could improve the situation.

My code is the following, contained in a central configuration file that is included by every script on the site:

(Line breaks and formatting added haphazardly to avoid breaking tables)

code:
function getdata($cxn,$fetchassoc,$query) {
    $QueryResult = mysqli_query($cxn,$query);
    if ( !$QueryResult )                           { $NoResults = 1; }
    else if ( mysqli_num_rows($QueryResult) == 0 ) { $NoResults = 1; }
    else                                           { $NoResults = 0; }
    if ( $NoResults and $fetchassoc == 2 ) {
        $rtn = 0;
    } else if ( $NoResults ) {
        $rtn = 'NONE';
    } else if ( $fetchassoc == 2 ) {
        $rtn = mysqli_fetch_row($QueryResult);
        $rtn = (int)$rtn[0];
    } else if ( $fetchassoc ) {
        $rtn = mysqli_fetch_assoc($QueryResult);
    } else {
        $rtn = $QueryResult;
    }
    while ( mysqli_more_results($cxn) ) { mysqli_next_result($cxn); }
    return $rtn;
}

// ...

function transtext($x) {
    global $TranslatableText;
    if ( isset($TranslatableText[$x]) ) { return $TranslatableText[$x]; }
    else                                { return 'MISSING TEXT ('.$x.')'; }
}

// ...

// $PageForText is a variable of type int that is set on some pages before the
// include() command, so that the following code loads text needed for that page.

if ( isset($PageForText) ) { $x = ', '.$PageForText; }
else                       { $x = ''; }

// `FormInUse` is the English version of the phrase.

$QR = getdata($cxn,
              0,
              'SELECT
                   `PhraseID`,
                   `FormInUse`
               FROM
                   `TransPhrase`
               WHERE
                   `Page` IN (1, 2'.$x.')'
              ) or die($readerrormessage);
if ( $QR == 'NONE' ) { die($unexpectederrormessage); }
while ( $row = mysqli_fetch_assoc($QR) ) {
    $TranslatableText[$row['PhraseID']] = $row['FormInUse'];
}

// $Language, along with a number of other preference settings, is determined by
// looking at the session data and loading the user's information from the
// database. The following code overwrites entries in array $TranslatableText with
// translated versions of phrases, where they exist in the database.

if ( $Language ) {
    $QR = getdata($cxn,
                  0,
                  'SELECT
                       `TransPhrase`.`PhraseID`,
                       `ChosenTranslatedPhrase`.`Translation`
                   FROM
                       `TransPhrase`
JOIN `ChosenTranslatedPhrase`
ON `TransPhrase`.`PhraseID` = `ChosenTranslatedPhrase`.`Phrase`
                   WHERE
                       `TransPhrase`.`Page` IN (1, 2'.$x.') AND
                       `ChosenTranslatedPhrase`.`Language` = '.$Language
                  ) or die($readerrormessage);
    if ( $QR != 'NONE' ) {
        while ( $row = mysqli_fetch_assoc($QR) ) {
            $TranslatableText[$row['PhraseID']] = $row['Translation'];
        }
    }
}

Hammerite
Mar 9, 2007

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

fletcher posted:

Or you could do:

php:
<?
function getData() {
    $memcache = new Memcache();
    $memcache->connect('memcache_host', 11211);

    $data = $memcache->get('key');
    if (data == null) {
        $data = getDataFromDatabase();
        $memcache->add('key', $data, false, 30);
    }
    return $data;
}
?>

I looked around and can't work out what the security implications are of using this.

Assume that my hosting provider has set up memcached in a secure fashion, so that the only things that can read and alter memcached information are applications run by my hosting provider, or scripts running on my site or other sites with the same host. Then is there anything to stop another site on the same hosting going into memcached and editing all of the data I've stored there to say "Screw Hammerite's users, you all smell of farts"?

Peanut and the Gang
Aug 24, 2009

by exmarx
Yes, I think they could, since memcache doesn't care about a username/password. But, with Memcache you can't enumerate through key names, so no one else will be able to know which names you're using. If you auto prefix each get/set key with the same random string, no one else will be able to mess with your stuff as long as they don't know that string.

gwar3k1
Jan 10, 2005

Someday soon
I'm confusing myself and maybe I'm missing the point of half of this code (having written it following a tutorial). I'm trying to hide a page behind session authentication or show a login screen if the authentication fails.

Am I doing this right?

php:
<?php
  session_start();
  
  function logged_in()
  {  
    if(isset($_SESSION['initiated']))
    {
    // Session has begun
    
    if(isset($_SESSION['HTTP_USER_AGENT']))
    {
      // Compare stored user agent with hashed current user agent
      if($_SESSION['HTTP_USER_AGENT'] == sha1($_SESSION['HTTP_USER_AGENT']))
      {
        // User agent matches session user agent
        
        // Hash current user agent
        $string $_SERVER['HTTP_USER_AGENT'];
        $string .= 'TKNuHSH0';
        
        for($i 1$i <= 10$i++)
        {
          $string sha1($string);
        }
        
        // Compare hashed user agent with url
        if($_GET['fpnt'] == $string)
        {
          // Allow access
          // Check user name & password
        }
        else
        {
          // Deny access
          $_SESSION = array(); // Unset Session variables
          session_destroy();   // Destroy the session
          header('Location: login page');
        }
      }
      else
      {
        // User agent has changed: Session being handled from another app
        $_SESSION = array(); // Unset Session variables
        session_destroy();   // Destroy the session
        header('Location: login page');
      }
    }
    else
    {
      // Assign hashed user agent in session
      $_SESSION['HTTP_USER_AGENT'] = sha1($_SERVER['HTTP_USER_AGENT']);
    }
  }
    else
    {
    // No Session
    
    // Create an instance of the session
    session_regenerate_id();
    $_SESSION['initiated'] = true;
    
    // Hash current user agent
    $string $_SERVER['HTTP_USER_AGENT'];
    $string .= 'TKNuHSH0';
        
    for($i 1$i <= 10$i++)
    {
      $string sha1($string);
    }
    
    $fpnt $string;
    
        // Check username and password, view client page if correct
    header('Location: client page');
    }
  }
?>

Edit: I've just noticed that I seem to have blatant problems with my user agent hashing conditional statements. If anyone could still suggest whether I'm approaching this in a right or wrong way (using header to reloacate to a login page for example), I'd appreciate it.

gwar3k1 fucked around with this message at 23:01 on Feb 22, 2010

Hammerite
Mar 9, 2007

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

fletcher posted:

Or you could do:

php:
<?
function getData() {
    $memcache = new Memcache();
    $memcache->connect('memcache_host', 11211);

    $data = $memcache->get('key');
    if (data == null) {
        $data = getDataFromDatabase();
        $memcache->add('key', $data, false, 30);
    }
    return $data;
}
?>

When I try to run a test page to see whether I can get memcached to work, I get one of the following error messages depending on whether I use object oriented or procedural style:

Fatal error: Class 'Memcache' not found in [path]/public_html/testmemcached.php on line 2

Fatal error: Call to undefined function memcache_connect() in [path]/public_html/testmemcached.php on line 4

Does this indicate that my hosting provider has not installed memcached, or is there some include() command that I have omitted? Searching seems to suggest not. I have no control over what PHP extensions are available, other than by requesting that they be installed.

DoctorScurvy
Nov 11, 2005
More of a passing curiosity, really

Hammerite posted:

Does this indicate that my hosting provider has not installed memcached
Run a script with the following code:
php:
<?php phpinfo(); ?>
This will show you everything available to you. Do a page search for 'memcache'; this should help you determine if it is installed.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
Looks like my hosting provider doesn't provide memcache. I'm going with a filesystem-based cache. I'm replacing the code I posted with

code:
function get_translation_module($modulenumber) {
    global $cxn,$Language,$TranslatableText;
    $TranslationFilename = TRANSLATION_CACHE_PREFIX.$Language.'-'.$modulenumber.'.txt';
    $getfromdb = false;
    if ( file_exists($TranslationFilename) and
         time() - filemtime($TranslationFilename) < 1000
         ) {
        $filecontents = file($TranslationFilename,FILE_IGNORE_NEW_LINES);
        if ( is_array($filecontents) ) {
            for ($i=0;2*$i+1<count($filecontents);$i++) {
                $TranslatableText[$filecontents[2*$i]] = $filecontents[2*$i+1];
            }
        } else {
            $getfromdb = true;
        }
    } else {
        $getfromdb = true;
    }
    if ( $getfromdb ) {
        if ( $Language ) {
            $queryresult = getdata($cxn,
                                   0,
                                   'SELECT
                                        `TransPhrase`.`PhraseID`,
                                        IFNULL(
                                            `ChosenTranslatedPhrase`.`Translation`,
                                            `TransPhrase`.`FormInUse`
                                        ) AS `FormInUse`
                                    FROM
                                        `TransPhrase`
LEFT JOIN `ChosenTranslatedPhrase`
ON `TransPhrase`.`PhraseID` = `ChosenTranslatedPhrase`.`Phrase`
                                    WHERE
                                        `TransPhrase`.`Page` = '.$modulenumber.' AND
                                        `ChosenTranslatedPhrase`.`Language` = '.$Language);
        } else {
            $queryresult = getdata($cxn,
                                   0,
                                   'SELECT
                                        `PhraseID`,
                                        `FormInUse`
                                    FROM
                                        `TransPhrase`
                                    WHERE
                                        `Page` = '.$modulenumber
                                   );
        }
        if ( $queryresult == 'NONE' ) {
            file_put_contents($TranslationFilename,"0\n0");
        } else {
            $filecontents = array();
            while ( $row = mysqli_fetch_assoc($queryresult) ) {
                $TranslatableText[$row['PhraseID']] = $row['FormInUse'];
                $filecontents[] = $row['PhraseID'];
                $filecontents[] = $row['FormInUse'];
            }
            file_put_contents($TranslationFilename,implode("\n",$filecontents));
        }
    }
}

if ( !isset($TrivialPage) ) {
    get_translation_module(1);
    get_translation_module(2);
}
The function get_translation_module() will then be called in the appropriate places.

jetviper21
Jan 29, 2005

Hammerite posted:

Looks like my hosting provider doesn't provide memcache. I'm going with a filesystem-based cache. I'm replacing the code I posted with

Before you go with file store do they have some sort of byte code cache like apc or xcache installed? you could use this the same way as memcache

Hammerite
Mar 9, 2007

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

jetviper21 posted:

Before you go with file store do they have some sort of byte code cache like apc or xcache installed? you could use this the same way as memcache

Thanks for the suggestion, but a quick scan of phpinfo() output suggests none of this is available.

Have implemented filesystem-based cache thing now. Appears to be working as expected.

Big Nubbins
Jun 1, 2004
Not sure if this is a question better suited for the "small web development questions" thread, but I'm looking for recommendations on an OO framework for PHP.

When I started working at the place I'm at now, I inherited a 10 year old proprietary CMS. Any time we make changes to the database, we run a Perl script that generates a library of classes that provide setter/getter methods and a host of other functions, handle relationships between tables, etc.

I'm aware that there are PHP5-based frameworks that essentially replace this system and are probably more sophisticated. We're at a pretty good point in the development cycle of the software where we can discuss radically changing our methods and take a direction away from our old proprietary framework and use one that lets us develop software faster. I'm looking at Zend but if others have experience with other systems and can steer me in the right direction, I'd appreciate it.

epswing
Nov 4, 2003

Soiled Meat
Give this a read, it's a pretty comprehensive introduction To the Kohana PHP5 framework, which is OOP and follows MVC.

http://dev.kohanaphp.com/projects/kohana2/wiki/Kohana101

Adbot
ADBOT LOVES YOU

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

greasy digits posted:

I'm aware that there are PHP5-based frameworks that essentially replace this system and are probably more sophisticated. We're at a pretty good point in the development cycle of the software where we can discuss radically changing our methods and take a direction away from our old proprietary framework and use one that lets us develop software faster. I'm looking at Zend but if others have experience with other systems and can steer me in the right direction, I'd appreciate it.

You may find this interesting.

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