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
epswing
Nov 4, 2003

Soiled Meat

DholmbladRU posted:

When I execute the fallowing code I get one column not seperate4d by ','

So what is it separated by?

Adbot
ADBOT LOVES YOU

DholmbladRU
May 4, 2006

epswing posted:

So what is it separated by?

Nothing, it would be like this.


value1
value2
value3


I opened the csv file up in notepad++ if that matters.

KuruMonkey
Jul 23, 2004

DholmbladRU posted:

I am trying to get the basics of this fputcsv(). When I execute the fallowing code I get one column not seperate4d by ','. However I am trying to get a row seperated by ','

What is in $columnHeadArray ?

This works:

php:
<?
    $data = array(
        array('hello', 'world'),
        array('more', 'data')
    );


    $fh = fopen('out.csv', 'w');
    if($fh)
    {
        foreach($data as $datum)
            fputcsv($fh, $datum);
            
        fclose($fh);
    }
?>
output:
code:
hello,world
more,data

(notice the extra newline)

But mostly notice the structure of $data: an array containing arrays for each line. If your structure is just an array, you're asking for one value per line in your code.

Edit: which may well mean you don't want a loop at all: one call to fputcsv per line you want to write, not per value to write.

KuruMonkey fucked around with this message at 11:53 on Oct 27, 2010

FamousThomas
Jul 16, 2006

Hey, Fry. Wake up, it's me, BIGFACE!
I'm going nuts over here with this little problem. A calendar I wrote is counting November 7th twice.

code:
//11/01/10 02:00:00
$start = 1288591200;

for ($x = 0; $x <= 7; $x++){
	echo date('m/d/y H:i:s', $start);
        // ADD 24 HOURS
	$start += (60 * 60 * 24);
	echo "<br/>";
	echo date('m/d/y H:i:s', $start);
	echo "<br/>------------------------<br/>";
}
For some reason when it hits the 7th it only adds 23 hours. Has anyone had this issue before? is this a known bug?

code:
11/01/10 00:00:00
11/02/10 00:00:00
------------------------
11/02/10 00:00:00
11/03/10 00:00:00
------------------------
11/03/10 00:00:00
11/04/10 00:00:00
------------------------
11/04/10 00:00:00
11/05/10 00:00:00
------------------------
11/05/10 00:00:00
11/06/10 00:00:00
------------------------
11/06/10 00:00:00
11/07/10 00:00:00
------------------------
11/07/10 00:00:00
11/07/10 23:00:00
------------------------
11/07/10 23:00:00
11/08/10 23:00:00
------------------------

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

FamousThomas posted:

I'm going nuts over here with this little problem. A calendar I wrote is counting November 7th twice.

code:
//11/01/10 02:00:00
$start = 1288591200;

for ($x = 0; $x <= 7; $x++){
	echo date('m/d/y H:i:s', $start);
        // ADD 24 HOURS
	$start += (60 * 60 * 24);
	echo "<br/>";
	echo date('m/d/y H:i:s', $start);
	echo "<br/>------------------------<br/>";
}
For some reason when it hits the 7th it only adds 23 hours. Has anyone had this issue before? is this a known bug?

code:
11/01/10 00:00:00
11/02/10 00:00:00
------------------------
11/02/10 00:00:00
11/03/10 00:00:00
------------------------
11/03/10 00:00:00
11/04/10 00:00:00
------------------------
11/04/10 00:00:00
11/05/10 00:00:00
------------------------
11/05/10 00:00:00
11/06/10 00:00:00
------------------------
11/06/10 00:00:00
11/07/10 00:00:00
------------------------
11/07/10 00:00:00
11/07/10 23:00:00
------------------------
11/07/10 23:00:00
11/08/10 23:00:00
------------------------

This year, daylight saving time ends in the United States on November 7. There are 25 hours in 11/07/10, so adding 24 doesn't take you to a full day.

FamousThomas
Jul 16, 2006

Hey, Fry. Wake up, it's me, BIGFACE!
Lousy farmers.

Thanks, buddy

Munkeymon
Aug 14, 2003

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



FamousThomas posted:

I'm going nuts over here with this little problem. A calendar I wrote is counting November 7th twice.

Don't increment time stamps by seconds if you want to get the right answers - use strtotime:
php:
<?
$day = strtotime('Oct 6 2010');
echo date('c', $day);  //2010-10-06T00:00:00-05:00
$day = strtotime('+1 day', $day);
echo date('c', $day)r; //2010-10-07T00:00:00-05:00
$day = strtotime('+1 day', $day);
echo date('c', $day);  //2010-10-08T00:00:00-05:00
?>

DholmbladRU
May 4, 2006

KuruMonkey posted:

What is in $columnHeadArray ?

This works:

php:
<?
    $data = array(
        array('hello', 'world'),
        array('more', 'data')
    );


    $fh = fopen('out.csv', 'w');
    if($fh)
    {
        foreach($data as $datum)
            fputcsv($fh, $datum);
            
        fclose($fh);
    }
?>
output:
code:
hello,world
more,data

(notice the extra newline)

But mostly notice the structure of $data: an array containing arrays for each line. If your structure is just an array, you're asking for one value per line in your code.

Edit: which may well mean you don't want a loop at all: one call to fputcsv per line you want to write, not per value to write.


columnheadarray is like this

php:
<?
$columnHeadArray[0] = 'Input Variable';
$columnHeadArray[1] = 'Amount';
$columnHeadArray[2] = 'Month/Butget Item';
$columnHeadArray[3] = 'August';
$columnHeadArray[4] = 'September';
$columnHeadArray[5] = 'October';
$columnHeadArray[6] = 'November';?>

KuruMonkey
Jul 23, 2004

DholmbladRU posted:

columnheadarray is like this

php:
<?
$columnHeadArray[0] = 'Input Variable';
$columnHeadArray[1] = 'Amount';
$columnHeadArray[2] = 'Month/Butget Item';
$columnHeadArray[3] = 'August';
$columnHeadArray[4] = 'September';
$columnHeadArray[5] = 'October';
$columnHeadArray[6] = 'November';?>

And you want:

Input Variable,Amount,Month/Budget Item,August,September,November

as the line in the file?

then you just want ONE call to fputcsv:

php:
<?
fputcsv($fh, $columnHeaderArray);
?>
You want to call fputcsv once per line you want in the file, so you want one array per line too. If you have a lot of records to spit into the file, you want an array of arrays as in my example, then loop through the outer array only.

An example that might parallel what you're doing:
php:
<?
// headers: just the one array
$headers = array('first_name', 'last_name', 'gender');

// records: one array per line, wrapped in an array of all the lines
$records = array(
  array('Barney', 'Rubble', 'Male'),
  array('Betty', 'Rubble', 'Female'),
  array('Wilma', 'Flintstone', 'Female'),
  array('Fred', 'Flintstone', 'Male')
);

$fh = fopen('flintstones.csv', 'w');
if($fh)
{
  fputcsv($fh, $headers);  // headers just the once
  foreach($records as $record) // then each record in turn
  {
    fputcsv($fh, $record);
  }
  fclose($fh);
}
?>
Will output as flinstones.csv:

code:
first_name,last_name,gender
Barney,Rubble,Male
Betty,Rubble,Female
Wilma,Flinstone,Female
Fred,Flintstone,Female

Again with the vestigial newline (when READING these files, you need to account for the possibility!)

KuruMonkey fucked around with this message at 11:49 on Oct 28, 2010

Fluue
Jan 2, 2008
I'm learning OOP PHP right now and I have a question about intiating classes inside another class. Is this considered a faux pas?

Right now I have:

php:
<?

class DatabaseControls{
    
    private $db_host = *******
    private $db_name = *******
    private $db_user = *******
    private $db_pass = *******

        
        function db_connect(){
            $connection = mysql_connect($this->db_host,$this->db_user,$this->db_pass);
                if(!$connection)
                {
                    die ("Could not connect: " . mysql_error());
                }
            $select_db = mysql_select_db($this->db_name, $connection);
            
        }
        
        function db_query($query){
            $result = mysql_query($query) or die ("There was an error while running the query: " . mysql_error());
            return $result;
        }
}//end database controls



class Authenticate {
    
    public $db;
    
    function __construct(){
        
        $this->db = new DatabaseControls();
        
        
    }//end constructor
    
    function checkUserExists(){
        $result = $this->db->db_query("SELECT * FROM cake_users WHERE username='verkaufer'");
        $num = $this->db->db_numRows($result);
      }
}//end authenticate
?>
(Ignore how I have a static value for "where usrename=", I am just tinkering)

The way it is executed is like so:

php:
<?
require_once "auth.php";

$db = new DatabaseControls();
$db->db_connect();

$auth = new Authenticate();
$exists = $auth->checkUserExists();
?>
Is there a better way to do this? Should I be using "extends" in this case?

musclecoder
Oct 23, 2006

I'm all about meeting girls. I'm all about meeting guys.
Yes, this is a bad way of doing things. The reason being it's harder to write unit tests because the constructor of Authenticate always requires a valid DatabaseControls object. The preferred way of doing this is called dependency injection.

php:
<?
class Authenticate {
  private $db;

  public function __construct() {

  }

  public function attachDb(DatabaseControls $db) {
    $this->db = $db;
    return $this;
  }

  public function checkUserExists() {
    $db = $this->checkDb();
    // rest of code here
  }

  private function checkDb() {
    if ( is_null($this->db) ) {
      throw new Exception('a valid DB object is not attached');
    }
    return $this->db;
  }
}
?>
Now, you can write some tests to ensure that attachDb() can only take DatabaseControls objects and checkUserExists() requires a valid DatabaseControls object before it can be used.


php:
<?
require_once 'PHPUnit/Framework.php';

class AuthenticateTest extends PHPUnit_Framework_TestCase {

  /**
   * @expectedException PHPUnit_Framework_Error
   */
  public function testAttachDb_RequiresValidDbObject() {
    // You could optionally write a dataProvider that attempts to inject many data types
    $authenticate = new Authenticate;
    $authenticate->attachDb(NULL);
  }

  public function testAttachDb_DbIsAttached() {
    $authenticate = new Authenticate;
    $this->assertType('Authenticate', $authenticate->attachDb($this->getMock('DatabaseControls'));
  }

  /**
   * @expectedException Exception
   */
  public function testCheckUserExists_RequiresDbObject() {
    $authenticate = new Authenticate;
    $authenticate->checkUserExists();
  }

  // Rest of your tests here
}
?>
Also, use PDO.

Edit: And stop with the stupid // end constructor, // end function(), // end if bullshit. Every modern editor can brace match so it's easy to find where they end.

musclecoder fucked around with this message at 23:41 on Oct 28, 2010

DholmbladRU
May 4, 2006
Yeah something like that.

I am trying to do this

code:
header, header, header, header, header, header, header, header, (<---- got this part)
$arrayKey,  (space),  (space), $arrayValue,  $arrayValue,  $arrayValue, 
$arrayKey2,  (space),  (space), $arrayValue2,  $arrayValue2,  $arrayValue2,
currently all my arrays are set up in a variable like to said

php:
<?
$records = array( $incomeArray, $yearlyExpArray, $semExpArray, $monthExpArray);?>
I am trying to fputcsv out the array key and two spaces, then have the array value be put 12 times(one for each month)

I was thinking about doing this in a function then calling this function for each $records. Or does that makes no sense?

php:
<?
   function getArray($tempArray) {
        //add key and 2 empty values to begining of array
   foreach ($tempArray as $key => $value)
        {
        //add one value for each month to array
    }
  
  }
?>

Begby
Apr 7, 2005

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

musclecoder posted:

OOP stuff

Excellent example musclecoder.

Is there any reason though that you aren't doing injection on your constructor? I usually go the constructor approach and throw an exception right there instead of doing an assertion later on.

As it is you are doing an assertion every time $db is used when you could be doing it once in the constructor.

Secondly, if testing for null in the constructor, the exception thrown will point to where the constructor is called (where it really needs to be fixed) instead of being thrown where you are calling a different method, which could be thousands of lines away or in a completely different file.

gwar3k1
Jan 10, 2005

Someday soon
I'm having trouble with a PDO update. I have a comments counter that should update itself, but doesn't:

php:
<?
$SQL = $db->prepare("update blogposts set blog_commentcount = ((select blog_commentcount
 from blogposts where blog_id = :blog)+1) where blog_id = :blog;");
$SQL->bindParam(":blog", $cleanvars[3]);
$SQL->execute();?>
I'm using a MySQL database, and I know that the query (when replaced with a blog_id) pulls data from the database - I tried it in phpmyadmin. I don't get an error when the code gets to this point, but the comment count doesn't increment. The database user definitely has update and select permissions.

Any suggestions?

Yay
Aug 4, 2007

gwar3k1 posted:

I'm using a MySQL database, and I know that the query (when replaced with a blog_id) pulls data from the database - I tried it in phpmyadmin. I don't get an error when the code gets to this point, but the comment count doesn't increment. The database user definitely has update and select permissions.

Any suggestions?
Presumably you've run into the bug/feature/version difference that is binding parameters. Try binding 2 parameters, :blog1 and :blog2 -- yes, with the same data.

Edit: looking at the query, why aren't you just doing incrementfield=incrementfield+1?
Edit 2: Oh, guy below me said the same re: incrementfield, before I'd saved.

Yay fucked around with this message at 18:33 on Oct 29, 2010

musclecoder
Oct 23, 2006

I'm all about meeting girls. I'm all about meeting guys.

Begby posted:

Excellent example musclecoder.

Is there any reason though that you aren't doing injection on your constructor? I usually go the constructor approach and throw an exception right there instead of doing an assertion later on.

As it is you are doing an assertion every time $db is used when you could be doing it once in the constructor.

Secondly, if testing for null in the constructor, the exception thrown will point to where the constructor is called (where it really needs to be fixed) instead of being thrown where you are calling a different method, which could be thousands of lines away or in a completely different file.

I don't like putting it in the constructor because it makes having to have a mock object each time you create the object in your tests. It's not a huge thing, and setUp() can handle creating the mock database object for you, but I prefer to attach it at a later point. For example, you're writing a test for a method of the class that doesn't require the database at all. No need to inject it into the constructor. Personal preference though.

You're right, but I just extend the Exception class and have a custom exception that includes a trace. Just go back one more trace level and you have the method that called checkDb().

To gwar3k1, what is that?

code:
UPDATE blogposts SET blog_commentcount = blog_commentcount + 1 WHERE blog_id = :blog
That should work just fine. Doing a sub-select to do an update seems like overkill and probably isn't supported by your driver.

gwar3k1
Jan 10, 2005

Someday soon
Thanks, getting rid of the inner select fixed it. I don't know why I thought it was necessary in the first place.

DholmbladRU
May 4, 2006
I am trying to print out the fallowing. But for some reason the middle loop is only adding the key 1 time.

code:
 $key, space, space, $value, $key, (then put the key 12 times)
php:
<?


foreach($records as $record) // then each record in turn
  {
  
    
        foreach ($record as $key => $value)
            {
            
            $temp[1] = $key;
            $temp[2] = '';
            $temp[3] = '';
            $temp[4] = $value;
            $temp[5] = $key;
        
                for($i = 6; $i <= 17; ) {
                    $temp[i] = $value;
                    $i++;
                    }
            fputcsv($file,$temp);
            
         echo $record;
        }
     }


?>

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

DholmbladRU posted:

php:
<?
                    $temp[i] = $value;
?>
You're assigning it to $temp["i"], rather than $temp[6]. If you had notice reporting on, it would tell you that constant i does not exist, assuming "i".

Moral of the story: Always develop with error and notice reporting turned on. (Though IMO I think that one should be handled as a warning rather than a notice)

Golbez fucked around with this message at 22:30 on Nov 1, 2010

DholmbladRU
May 4, 2006
moral of the story, look closely at your code.. should be $i, thanks.

DholmbladRU fucked around with this message at 00:49 on Nov 2, 2010

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
I'm taking currency form input. I want to make sure they don't do something crazy and give me fractional cents. What's an easy way to make sure that, if there's a decimal point, only allow two digits after it? For example, if they put in 25.011, I want to know that it's wrong. Right now I'm trying a simple regex (\.\d{3}) but was wondering if there were a more elegant way. I thought about comparing the input to number_format($str, 2), but that only works if I also pad the input with zeroes, and at that point it's getting more complex than a regex.

McGlockenshire
Dec 16, 2005

GOLLOCKS!

Golbez posted:

I'm taking currency form input. I want to make sure they don't do something crazy and give me fractional cents. What's an easy way to make sure that, if there's a decimal point, only allow two digits after it? For example, if they put in 25.011, I want to know that it's wrong. Right now I'm trying a simple regex (\.\d{3}) but was wondering if there were a more elegant way. I thought about comparing the input to number_format($str, 2), but that only works if I also pad the input with zeroes, and at that point it's getting more complex than a regex.

Regexes are always fun.
code:
function test_regex($input) {
    $matches = array();
    if(preg_match('/
    ^                              # Front anchor
      (?:                          # Non-capturing group with two options:
        (?P<just_dollars>\d+)      # Capture one or more digits named "just_dollars"
        |                          # or
        (?P<not_just_dollars>\d+)? # Capture one or more digits, maybe, named "not_just_dollars"
        (?:                        # Then a non-capturing group of
          \.                       # a period
          (?P<cents>\d{1,2})       # followed by either one or two digits, capture to "cents"
        )                          # close inner non-capturing
      )                            # close outer non-capturing
    $/x', $input, $matches)) {
        return $matches;
    }
    return false;
}
var_dump(test_regex('1'));
var_dump(test_regex('1.2'));
var_dump(test_regex('1.23'));
var_dump(test_regex('1.234'));
var_dump(test_regex('.234'));
var_dump(test_regex('.23'));
var_dump(test_regex('.2'));
var_dump(test_regex('.'));
var_dump(test_regex('arglebargle'));
Or you could just explode on the dot and use strlen. Or do the number_format thing. Regexes aren't always the least complex solution.

gwar3k1
Jan 10, 2005

Someday soon
Doesn't round() do what you want?

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
Or I could use the tiny regex I posted to make sure there aren't three digits after the decimal? :) I know using a regex is often not the simplest solution, which is why I was querying for a simpler, more elegant solution. That monster you posted would seem to whitelist, but all I really need is a blacklist: return !preg_match('/\.\d{3}/', $string)

The explode and strlen on the period is a good idea, though.

quote:

Doesn't round() do what you want?
I don't want to round it, I want to reject it outright. There's no reason they'd be giving me a fractional cent, so it's considered an invalid entry. And comparing the input with the rounded value still gives me the problem of having to pad the input string with zeroes, or the situation with whole numbers that don't have periods.. I may be making it more complex than it is. :P

gwar3k1
Jan 10, 2005

Someday soon
I think you've got your solution but another option would be two input fields, limiting the second to maxlength of 2 and concatenate the decimal in code: [__].[__]

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

gwar3k1 posted:

I think you've got your solution but another option would be two input fields, limiting the second to maxlength of 2 and concatenate the decimal in code: [__].[__]

I've never seen this used before, doesn't seem like a very good idea either tbh.

cka
May 3, 2004
Why regex? sprintf('%.2f', $value) should do exactly what you need it to do for this...

code:
# php ./honk.php
string(4) "1.00"
string(4) "1.20"
string(4) "1.23"
string(4) "1.23"
string(4) "0.23"
string(4) "0.23"
string(4) "0.20"
string(4) "0.00"
string(4) "0.00"

# cat honk.php
<?php
function test_regex($input)
{
  return sprintf("%.2f", $input);
}
var_dump(test_regex('1'));
var_dump(test_regex('1.2'));
var_dump(test_regex('1.23'));
var_dump(test_regex('1.234'));
var_dump(test_regex('.234'));
var_dump(test_regex('.23'));
var_dump(test_regex('.2'));
var_dump(test_regex('.'));
var_dump(test_regex('arglebargle'));
From that you can do whatever with the values that return 0.00, or test them in the function to make sure they're not alphabetic strings or whatever.

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
Thanks, but it's padding the number with zeroes, which I don't want, because it then means I'd have to pad both the input and the output with zeroes in order to see if they differ, and then I'm comparing the result of this function to... the result of this function. It's not that I want to trim or round; I want to know and reject. So far the explode idea seems to work for what I need.

If there were an easy one that would take this...
code:
var_dump(test_regex('1'));
var_dump(test_regex('1.2'));
var_dump(test_regex('1.23'));
var_dump(test_regex('1.234'));
var_dump(test_regex('.234'));
and return this, essentially the same string but with the number after the decimal cut to two digits...
code:
string(4) "1"
string(4) "1.2"
string(4) "1.23"
string(4) "1.23"
string(4) ".23"
...then I'd be happy, I could compare the input with the output and see if there's a difference. (or, rather, the function itself could do that, and return a boolean) But at the moment it seems that exploding and counting the length after the period works well:
php:
<?
function foo($s, $limit = 2)
{
    switch (substr_count('.', $s))
    {
        // No decimal, no problems
        case 0:
            return true;
        // One decimal, see how big the area to the right of it is
        case 1:
            $a = explode('.', $s);
            return !(strlen($a[1]) > $limit);
        // More than one decimal, big problems
        default:
            return false;
    }
}
?>
It looks clunky, but it's only a few statements and it doesn't use a regex. Also, I'd like to take this moment to again ask PHPDev to hurry up and give us array dereferencing, so I can cut that middle section to return !(strlen(explode('.', $s)[1]) > $limit);

gwar3k1 posted:

I think you've got your solution but another option would be two input fields, limiting the second to maxlength of 2 and concatenate the decimal in code: [__].[__]
Interesting idea, but since this app also has to take input from a CSV, I need to also be able to reject fractional cents in that, so relying on the form layout won't work.

musclecoder
Oct 23, 2006

I'm all about meeting girls. I'm all about meeting guys.
php:
<?
sprintf('%01.2f', '1.234');?>
Will truncate that to 1.23. Try that.

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

musclecoder posted:

php:
<?
sprintf('%01.2f', '1.234');?>
Will truncate that to 1.23. Try that.

But it also converts 1.2 to 1.20, meaning I can't compare input and output to see if there's a problem. I mean, I could then trim zeroes, but then for 1 to 1.00, I'd have to make sure to also trim the ., and at this point we're approaching annoying complexity again. And, it also doesn't warn me when there's more than one decimal in the string.

This would run something like...
php:
<?
function foo($s, $limit = 2)
{
    $x = sprintf('%01.'.$limit.'f', $s);
    return ($x === $s || rtrim(ltrim($x, '0'), '0.') === $s);
}
?>
hm. OK, maybe not as bad as I thought.

Golbez fucked around with this message at 14:49 on Nov 3, 2010

musclecoder
Oct 23, 2006

I'm all about meeting girls. I'm all about meeting guys.
Could you just do a

php:
<?
round(sprintf('%01.2f', '1.20'), 2);?>
to knock off the hanging 0 and if there's a non-zero there, it'll be in the final string?

Then wrap a strval() to cast it back to a string.

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

musclecoder posted:

Could you just do a

php:
<?
round(sprintf('%01.2f', '1.20'), 2);?>
to knock off the hanging 0 and if there's a non-zero there, it'll be in the final string?

Then wrap a strval() to cast it back to a string.
Ooh, we might have a winner here. Returns 1.2 for 1.2; 1.22 for 1.223; and 1 for 1. And, 1.2 for 1.2.2, which gets rid of the decimal problem. Only problem is it adds a leading zero if none exists, but that's easily trimmed. (And I'd still want to trim zeroes from both sides when comparing anyway)

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
In an almost completely unrelated aside, it looks like there's no "greater/lesser than or identical" comparison operator?

So, if I do $s <= 10, it will return true if $s is 10 or "10". There's no way to do $s <== 10, to force it to return true iff $s is 10, without adding || $s === 10. I guess this makes sense, since there's no way to force typing on the >/< side of the operator except through casting, but it was still a small surprise.

revmoo
May 25, 2006

#basta
This is driving me crazy. How do you use substr? It keeps outputting the entire variable string no matter what arguments I give it.

This is the line I'm using:

substr($thefile, 5);

This does not make any changes to the var $thefile no matter what arguments I give it. What am I doing wrong?

EDIT: For some reason changing it to $thefile = substr($thefile, 5); makes it work, but I don't understand why.

revmoo fucked around with this message at 17:42 on Nov 3, 2010

Munkeymon
Aug 14, 2003

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



revmoo posted:

EDIT: For some reason changing it to $thefile = substr($thefile, 5); makes it work, but I don't understand why.

Because the function doesn't modify the string in place, it returns a copy of the part of the string you specify that you have to explicitly store or pass on to something else.

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

revmoo posted:

This is driving me crazy. How do you use substr? It keeps outputting the entire variable string no matter what arguments I give it.

This is the line I'm using:

substr($thefile, 5);

This does not make any changes to the var $thefile no matter what arguments I give it. What am I doing wrong?

EDIT: For some reason changing it to $thefile = substr($thefile, 5); makes it work, but I don't understand why.

substr($thefile, 5) won't change anything itself, it will simply return the substring. Which is exactly why you need to assign it to the variable to get it to do anything.

PHP manual posted:

Returns the extracted part of string or FALSE on failure.

Edit: To illustrate why it would be a bad thing for commands like that to edit their input...

Example one: substr('test', 2) - How's it going to edit 'test'?
Example two: What if you want to do other things with that string? You'd have to assign it to another variable in the first place.
php:
<?
$s = 'Test string';
$sub = $s;
substr($sub, 5); // Let's say this changes $sub to 'string'
echo 'Dropping the first five characters of '.$s.' gives us '.$sub;

// As opposed to...

$s = 'Test string';
$sub = substr($s, 5); // Assigns 'string' to $sub
echo 'Dropping the first five characters of '.$s.' gives us '.$sub;
?>

Golbez fucked around with this message at 18:00 on Nov 3, 2010

revmoo
May 25, 2006

#basta
Makes sense, thanks for the lesson!

gwar3k1
Jan 10, 2005

Someday soon
e: wrong thread

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
I have a pretty large page with multiple POST functions coming back to it as flow control. So from the main menu/default part of the script (contained in an else block at the bottom of the file), I have a quicksearch box that takes me to another part (contained in an elseif (isset($_POST['quicksearch'])) in the middle of the file). If they put in an invalid search, I want it to come back to that default section and notify the user.

There are three ways of doing this:
1) Rejigger the file so that the elseif(isset($_POST['search'])) block and its associated procedures are contained inside the else block, so that any errors generated by said procedures can be displayed on that webpage.

2) Perversion 1: Use header() to send people back to the main menu (the only part that can be accessed without a $_POST, after all) with a parameter in the URL telling the page to print the URL.

3) Perversion 2: Use goto.

When I found myself actually coding #2 I wanted to come here and find out if that was beyond the pale and if I should just suck it up and use goto. I'd really rather not rejigger the flow of the file.

Edit: The universe wants me to be pure. I forgot that goto was only added in PHP 5.3 (which we don't run), and since this is happening in the middle of my script it's after headers, so header() won't work. Rejiggering it is!

Golbez fucked around with this message at 22:06 on Nov 3, 2010

Adbot
ADBOT LOVES YOU

John Capslocke
Jun 5, 2007
Is there any sane way to deal with XML-RPC? Any pointers/suggested reads would be appreciated.

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