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
moops
Jul 16, 2001

it's a typo

Golbez posted:

Out of curiosity, is there any way to skip the first argument in that? So like...

php:
<?
blah(,"you suck"); // "Hey Dave, you suck"
?>
?

In cases like that I usually set the defaults at the top of the function

php:
<?php

function blah($name=FALSE,$msg=FALSE)
{
 $name = ($name==FALSE) ? 'Dave' $name;
 $msg = ($msg==FALSE) ? 'Sup d00d' $msg;
 echo "Hey $name$msg<br>";
}

blah(); // "Hey Dave, Sup d00d"
blah("Larry"); // "Hey Larry, Sup d00d"
blah("Skippy","you suck"); // "Hey Skippy, you suck"
blah(FALSE"you suck"); // "Hey Dave, you suck"
blah(null"you suck"); // "Hey Dave, you suck"

?>

Adbot
ADBOT LOVES YOU

Sneaking Mission
Nov 11, 2008

Golbez posted:

Out of curiosity, is there any way to skip the first argument in that?

What you are thinking of is usually handled by Named Parameters in other languages. They let use explicitly define which values go with which parameter for a function.

So a function defined as f($a=1, $b=2, $c=3), instead of calling it as f(4, 5, 6) you can name the parameters: f(a=>7, b=>8, c=>9). Named parameters also let you reorder the position of the parameters in the function call: f(c=>9, a=>7, b=>9).

PHP does not have named parameters, though. They apparently had been talked about several years ago, however it looks like there isn't much chance of getting them added.

cka
May 3, 2004
You can always use func_get_args() in your function to sort of emulate named parameters/overloading functions... it'll take a bit more code to make the values match up to whatever you want the arguments to be, obviously, but it's somewhat doable. Probably not worth the time or code though.

php:
<?
function f()
{
  $args = func_get_args();
  print_r($args);
}

echo f(1, "test", "args");
echo f("test", "args");
?>
outputs:
code:
$ php ./af.php
Array
(
    [0] => 1
    [1] => test
    [2] => args
)
Array
(
    [0] => test
    [1] => args
)
edit: a slight modification makes named variables possible!

php:
<?
function f()
{
  $named=array();
  $args = func_get_args();
  foreach($args as $key => $val)
  {
    if (ereg("=", $val)) {
      $_tmp = split("=", $val);
      $named[$_tmp[0]] = $_tmp[1];
    }
  }
  print_r($named);
}
echo f("name=Dave", "message=Foo");
echo f("name=Steve", "message=Check this out!", "status=Checking...");
?>
code:
$ php ./af.php
Array
(
    [name] => Dave
    [message] => Foo
)
Array
(
    [name] => Steve
    [message] => Check this out!
    [status] => Checking...
)
Still probably not worth your time to do it this way, though

cka fucked around with this message at 02:08 on May 29, 2009

KuruMonkey
Jul 23, 2004

moops posted:

In cases like that I usually set the defaults at the top of the function

php:
<?php

function blah($name=FALSE,$msg=FALSE)
{
 $name = ($name==FALSE) ? 'Dave' $name;
 $msg = ($msg==FALSE) ? 'Sup d00d' $msg;
 echo "Hey $name$msg<br>";
}
?>


It is quite simply better to do:

php:
<?
function blah($name='Dave', $msg='Sup d00d')
{
  echo "Hey $name, $msg<br>";
}
?>
It is both more efficient because it eliminates your spurious test and assignment, and also does not obfuscate parameter type/meaning (FALSE is not valid input to your function; in your example this is a trivial issue, in a large and meaningful function it would not be).

supster
Sep 26, 2003

I'M TOO FUCKING STUPID
TO READ A SIMPLE GRAPH
You can't use func_get_args() to emulate named parameters because there way to set a key for the parameter.

If you really want to do it the best way is use an associative array as the parameter to the function and use that to extend an array of the default parameters. Something like this:


php:
<?php

function array_extend(&$array, &$defaults)
{
    foreach($defaults as $key => $value)
    {
        if(!isset($array[$key]))
            $array[$key] = $value;
    }
}

function array_check_required(&$array, &$required)
{
    foreach($required as $key)
    {
        if(!isset($array[$key]))
            throw new Exception("Required key $key missing.");
    }
}

function f($params = array())
{
    // all optional parameters and their default values.
    $params_default = array(
        'name' => 'default_name',
        'age' => 21,
    );
    // all keys of required parameters.
    $params_required = array('id');
    array_check_required($params$params_required);
    array_extend($params$params_default);
    
    // actual function body
    print_r($params);
}

f(array('id' => 1));
f(array('id' => 5'name' => 'new_name''age' => 12));
f();

And the output:
code:
Array
(
    [id] => 1
    [name] => default_name
    [age] => 21
)
Array
(
    [id] => 5
    [name] => new_name
    [age] => 12
)

Fatal error: Uncaught exception 'Exception' with message 'Required key id missing.' in /t.php:17
Stack trace:
#0 /t.php(30): array_check_required(Array, Array)
#1 /t.php(39): f()
#2 {main}
  thrown in /t.php on line 17

supster fucked around with this message at 23:23 on May 28, 2009

supster
Sep 26, 2003

I'M TOO FUCKING STUPID
TO READ A SIMPLE GRAPH

KuruMonkey posted:

It is quite simply better to do:
In a lot of cases it's simply not possible to use default values that you actually want to use and are forced to use FALSE (or NULL or whatever your preference is) because default values must be constant expressions and cannot be something like a variable or the result of another function.

moops
Jul 16, 2001

it's a typo

KuruMonkey posted:

It is quite simply better to do:

php:
<?
function blah($name='Dave', $msg='Sup d00d')
{
  echo "Hey $name, $msg<br>";
}
?>
It is both more efficient because it eliminates your spurious test and assignment, and also does not obfuscate parameter type/meaning (FALSE is not valid input to your function; in your example this is a trivial issue, in a large and meaningful function it would not be).

that doesn't really address Golbez's issue. He was wondering if there was a way to skip the first argument. I made no comment on if this was best practices, simply the way I've solved that issue in the past. Mostly in cases were refactoring was not a viable option.

KuruMonkey
Jul 23, 2004
If you want to emulate named parameters, func_get_args isn't going to do it for you, since you get a numerically indexed array of arguments from it. So thats not going to give you 'named' arguments as the order of arguments is still totally determining which is which.

Edit: and you still have to supply something for param 3 if you want to use param 4

However, an associative array WILL give you an analogue to named arguments, but not without effort.

Taking something based on moops' blah() function, we can do:

php:
<?
function blah($options=array())
{
  // we need our defaults:
  static $defaults = array('name'=>'Dave', 'message'=>'Hello, ');

  // ensure $options IS an array:
  $options = (is_array($options) ? $options : array($options));

  // use our parameters OR the defaults for unset keys:
  $options = array_merge($defaults, $options);
  // order is important in that call! later arrays overwrite

  // and give back a nice formatted message:
  return $options['message'].'<b>'.$options['name'].'</b><br>';
}

// now we can call:
echo blah(); // 'Hello, Dave'
echo blah(array('name'=>'KuruMonkey')); // 'Hello, KuruMonkey'
echo blah(array('message'=>'Whatup? ')); // 'Whatup? Dave'
?>
Obviously thats a less obnoxious call format if the arrays are not being defined as literals in the function call itself, but packaged up somewhere meaningful.

In general its too much trouble for what its worth, but I do use it in utility functions for things like:

php:
<?
function img($src, $alt, $attribs=array())
{
...
}
?>
To give a bunch of optional extra parameters that can be defined in any order or combination. (I usually do not have defaults as demonstrated above though)

KuruMonkey fucked around with this message at 08:21 on May 29, 2009

StrugglingHoneybun
Jan 2, 2005

Aint no thing like me, 'cept me.
I'm trying to make a page scan directories.
I'm confused on how to set a string of the directory I want it to scan.

$entrynum is set earlier in the page, and will increment at it goes along.

php:
<?php
$entrynumdir "content/ $+ $entrynum"
print_rscandir$entrynumdir ) );
?>

This throws up Parse error: syntax error, unexpected '$' in test.php

I was kind of grasping at straws with that one. I've tried several different ways. I'm sure it some basic function of strings I've yet to grasp.

edit: I need to use chdir() . I got it!

StrugglingHoneybun fucked around with this message at 05:51 on May 31, 2009

Recycle Bin
Feb 7, 2001

I'd rather be a pig than a fascist
I'm working on a simple gallery program for my website, and I'm in the middle of cleaning up my code. I replaced a bunch of the echo statements with heredocs for stuff like forms, but because I have to have my delimiter placed all the way to the left, I want to separate these heredoc statements in their own separate file to keep things organized. Problem is, these statements have variables, and if I stick my include statement at the top of the file, the variables will just show up as blanks when it comes time to call them. My questions are:

1) How can I make a call to a string containing variables from outside its original file?
2) Is there a more efficient way to do what I described? I'm fairly new at this.

Begby
Apr 7, 2005

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

Recycle Bin posted:

I'm working on a simple gallery program for my website, and I'm in the middle of cleaning up my code. I replaced a bunch of the echo statements with heredocs for stuff like forms, but because I have to have my delimiter placed all the way to the left, I want to separate these heredoc statements in their own separate file to keep things organized. Problem is, these statements have variables, and if I stick my include statement at the top of the file, the variables will just show up as blanks when it comes time to call them. My questions are:

1) How can I make a call to a string containing variables from outside its original file?
2) Is there a more efficient way to do what I described? I'm fairly new at this.

You have to put the include after where the variables are set.

You might want to look into an MVC framework. Codeignitor is pretty simple and easy to pick up. It helps you separate your view (in this case your heredoc stuff) from your program logic.

Munkeymon
Aug 14, 2003

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



Recycle Bin posted:

I'm working on a simple gallery program for my website, and I'm in the middle of cleaning up my code. I replaced a bunch of the echo statements with heredocs for stuff like forms, but because I have to have my delimiter placed all the way to the left, I want to separate these heredoc statements in their own separate file to keep things organized. Problem is, these statements have variables, and if I stick my include statement at the top of the file, the variables will just show up as blanks when it comes time to call them. My questions are:

1) How can I make a call to a string containing variables from outside its original file?
2) Is there a more efficient way to do what I described? I'm fairly new at this.

You can include or require at any point in the script and it's the same thing, conceptually, as pasting all that included code into the file at that point, so there is no 'other file' you need to worry about as long as you include what you need.

stoops
Jun 11, 2001
i have a db table of applicants.

when an applicant submits their info, they can also upload their resume.

to keep it simple, my table structure is

applicantID
first (first name)
last (last name)
resume (file name of resume uploaded)

---
all resumes are stored in resume folder on server.

my question is...is there any way i can search for WORDS inside each document of the resume folder?

what i want to implement is a form where you can enter "keywords", then on submission, it will look thru resume folder and spit out the resumes that match those keywords.

any help or point in the right direction is appreciated.

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

:dukedog:

It'll be a bit trickier if they're uploading MS Word docs and various other text formats but if you're somehow storing the resumes in a textfield, you can use fulltext search in MySQL most likely.

stoops
Jun 11, 2001

drcru posted:

It'll be a bit trickier if they're uploading MS Word docs and various other text formats but if you're somehow storing the resumes in a textfield, you can use fulltext search in MySQL most likely.

i'm only storing the resume name in the db field.

do you know of any php scripts that will actually look and search words within a directory's files.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

stoops posted:

i'm only storing the resume name in the db field.

do you know of any php scripts that will actually look and search words within a directory's files.

You can use PHPs file handling abilities to read each file in, search words, close, etc. Or you can use shell_exec() to use grep or whatever. I'd go with the latter, and make sure you are caching results or building an index of matches to avoid duplicate searches and so on.

KuruMonkey
Jul 23, 2004
Depending on how you upload, and the size/number of files involved, you might find it easier to manage converting the resumé to plain text as you upload it and put the plaintext version into the DB and search on THAT. (store original for retreival, store plaintext in DB to search against)

Assumes you have somewhere you can hook into to make the conversion as you upload/update, and aren't just FTPing up CVs to a directory.

supster
Sep 26, 2003

I'M TOO FUCKING STUPID
TO READ A SIMPLE GRAPH
Convert the document to plain text and then index that plain text (simplest by just storing it in a text field in your database and using full text search).

To convert the document to plain text you will need some sort of reader for the types of document you want to support - you cannot just read them in as ASCII files.

Tad Naff
Jul 8, 2004

I told you you'd be sorry buying an emoticon, but no, you were hung over. Well look at you now. It's not catching on at all!
:backtowork:
Before I kill myself any further, is there something in PHP already out there that functions as a proxy? I'm working on a mobile (i.e. PDA) interface to a highly organic (since 1996 if not before) site that has all manner of crap in it, from PDFs to JSP to Perl CGI to straight (if very nonstandard) HTML. The basic operation is:

code:
[url]http://site.com/m/index.php?page=http://site.com/requested_page.html[/url]
will return http://site.com/requested_page.html with images/embeds/style/script taken out and some other minimalization and URL rewriting to point back at the minimizer/proxy. It's working pretty well, but the thing that's blocking me is cookies, it seems. I'm using curl like so:

code:
        curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiefile);
        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiefile);
but the minified login page always complains that I have to turn cookies on. So, a) like I asked before, is there something like what I'm trying to do out there already, or b) am I totally wrong on that cookie business?

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

FeloniousDrunk posted:

Before I kill myself any further, is there something in PHP already out there that functions as a proxy? I'm working on a mobile (i.e. PDA) interface to a highly organic (since 1996 if not before) site that has all manner of crap in it, from PDFs to JSP to Perl CGI to straight (if very nonstandard) HTML. The basic operation is:

code:
[url]http://site.com/m/index.php?page=http://site.com/requested_page.html[/url]
will return http://site.com/requested_page.html with images/embeds/style/script taken out and some other minimalization and URL rewriting to point back at the minimizer/proxy. It's working pretty well, but the thing that's blocking me is cookies, it seems. I'm using curl like so:

code:
        curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiefile);
        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiefile);
but the minified login page always complains that I have to turn cookies on. So, a) like I asked before, is there something like what I'm trying to do out there already, or b) am I totally wrong on that cookie business?

I have successfully done this, so I know it can be done... I'd have to dig through my work machine's backup HD to look for my stuff, but this page here might give you an "ah-hah!" until I can find my stuff or somebody else can help you out:

http://www.weberdev.com/get_example-4555.html

Tad Naff
Jul 8, 2004

I told you you'd be sorry buying an emoticon, but no, you were hung over. Well look at you now. It's not catching on at all!
:backtowork:

Lumpy posted:

I have successfully done this, so I know it can be done... I'd have to dig through my work machine's backup HD to look for my stuff, but this page here might give you an "ah-hah!" until I can find my stuff or somebody else can help you out:

http://www.weberdev.com/get_example-4555.html

Gah, I did it. I was totally on the wrong track, of course. For anyone else doing this sort of thing, don't keep POSTing info when you're following redirects.

eHacked
Sep 30, 2003

CONGRATULATIONS!!! YOU ARE THE 6,127,436,218TH PERSON TO VIEW THIS USELESS POST. CLICK TO CLAIM YOUR PRIZE!!!

End of Life Guy posted:

I'm trying to make a page scan directories.
I'm confused on how to set a string of the directory I want it to scan.

$entrynum is set earlier in the page, and will increment at it goes along.

php:
<?php
$entrynumdir "content/ $+ $entrynum"
print_rscandir$entrynumdir ) );
?>

This throws up Parse error: syntax error, unexpected '$' in test.php

I was kind of grasping at straws with that one. I've tried several different ways. I'm sure it some basic function of strings I've yet to grasp.

edit: I need to use chdir() . I got it!

I know you got it but am I missing something here... You should have used single quotes, right? :

$entrynumdir = 'content/ $+ ' . $entrynum;

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

:dukedog:

Are there any reasons as to why this function gets occasionally slow?

php:
<?
    public function show_map($sector, $galaxy, $distance = 2)
    {
        $start_sector    = $this->galaxies[$galaxy]['start_sector'];
        $width            = $this->galaxies[$galaxy]['width'];
        $end_sector        = $start_sector + ( ($width * $this->galaxies[$galaxy]['height']) - 1 );
        $min            = $distance * -1;
        $tile            = 0;

        $map = array();

        for($l = $min; $l <= $distance; $l++)
        {
            $mid_of_line = ($sector + ($width * $l));

            if( ($mid_of_line < $start_sector) || ($mid_of_line > $end_sector))
                $mid_of_line = -1;

            $line = ceil(($mid_of_line - $start_sector + 1) / $width);
             $start_of_line = $width * ($line - 1) + $start_sector;
            $end_of_line = $start_of_line + $width;

            for($s = $min; $s <= $distance; $s++)
            {
                $current = $mid_of_line + $s;

                if( ($current < $start_of_line) || ($current >= $end_of_line) || ($current > $end_sector) )
                    $current = -1;

                if($current > 0)
                {
                    $map[$tile] = $this->info[$current];
                    $map[$tile]['sector'] = $current;
                    $css = "sector";
                    if($current == $sector)
                        $css .= " current";
                    if( in_array($current, $this->get_exits($sector)) )
                    {
                        $css .= " linked";
                        $map[$tile]['link'] = "./move.php?sector=$current";
                    }
                }
                else
                    $css = "explored sector";

                $map[$tile]['css'] = $css;

                $tile++;
            }
        }

        return $map;
    }?>
Could the fact that $sector is different on every page load as it is updated in MySQL have anything to do with it?

Begby
Apr 7, 2005

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

drcru posted:

Are there any reasons as to why this function gets occasionally slow?

php:
<?
    public function show_map($sector, $galaxy, $distance = 2)
    {
        $start_sector    = $this->galaxies[$galaxy]['start_sector'];
        $width            = $this->galaxies[$galaxy]['width'];
        $end_sector        = $start_sector + ( ($width * $this->galaxies[$galaxy]['height']) - 1 );
        $min            = $distance * -1;
        $tile            = 0;

        $map = array();

        for($l = $min; $l <= $distance; $l++)
        {
            $mid_of_line = ($sector + ($width * $l));

            if( ($mid_of_line < $start_sector) || ($mid_of_line > $end_sector))
                $mid_of_line = -1;

            $line = ceil(($mid_of_line - $start_sector + 1) / $width);
             $start_of_line = $width * ($line - 1) + $start_sector;
            $end_of_line = $start_of_line + $width;

            for($s = $min; $s <= $distance; $s++)
            {
                $current = $mid_of_line + $s;

                if( ($current < $start_of_line) || ($current >= $end_of_line) || ($current > $end_sector) )
                    $current = -1;

                if($current > 0)
                {
                    $map[$tile] = $this->info[$current];
                    $map[$tile]['sector'] = $current;
                    $css = "sector";
                    if($current == $sector)
                        $css .= " current";
                    if( in_array($current, $this->get_exits($sector)) )
                    {
                        $css .= " linked";
                        $map[$tile]['link'] = "./move.php?sector=$current";
                    }
                }
                else
                    $css = "explored sector";

                $map[$tile]['css'] = $css;

                $tile++;
            }
        }

        return $map;
    }?>
Could the fact that $sector is different on every page load as it is updated in MySQL have anything to do with it?

For one thing there is a lot going on there. I don't think anybody is going to get out a pencil and try to make an attempt to try and figure out what you are trying to do. Perhaps you should try to comment your code and/or simplify it a bit or break it into smaller functions.

I have no idea what $sector is or what you are talking about with the mysql thing.

The only thing I can see offhand is $distance. You are looping through it, then looping through it again within that loop.

So, if $distance is 1000, you will end up doing 2000 iterations ($min would be -1000), and 2000 iterations within that. This would mean the inner for loop would run 4,000,000 times, which turns out to be a lot of processing if you are doing in_array().

Not sure what your range is on $distance though, if it is always low numbers then thats probably not what is slowing it down.

edit: Also, what does $this->get_exits($sector) do? Does that do any db queries? You should note that if you comment it.

Begby fucked around with this message at 14:31 on Jun 5, 2009

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

:dukedog:

Sorry about the lack of comments. Here's a picture of what this actually does.



In this example $sector = 288 and $galaxy = 1. The green circle is where we are and the yellow boxes are where we can go.

$galaxy is not important right now and I've commented the code below to include their values.

php:
<?
giant wall of code?>
Whenever someone "moves" their $sector is updated in the MySQL database and then show_map() is called again. Reloading the page without moving seems to cause lag sometimes.

$this->get_exits($sector) gets an array of sectors that the sector links to. A list of all sectors and their links is gathered at the beginning of the page through MySQL and is stored in $this->info. get_exits() just gets the row $sector from the result array. It shouldn't be calling any new queries.

I appreciate any attempts at even reading this. Thanks!

Acer Pilot fucked around with this message at 08:37 on Jun 12, 2009

KuruMonkey
Jul 23, 2004
During the process of that function $sector doesn't get altered.

Does the output of $this->get_exits($sector); potentially alter independantly of the value of $sector?

If not call it once at the start of the function and then use that value repeatedly instead of calling it every iteration of your inner loop.


this is the same issue as doing this:

php:
<?
for($i=0; $i<count($big_array); $i++)
{
...
}
?>
when you should be doing this:
php:
<?
$limit = count($big_array);
for($i=0; $i<$limit; $i++)
{
...
}
?>
Basically don't do things in loops that don't vary during the loop, and the control of a loop is part of the loop.

KuruMonkey fucked around with this message at 19:40 on Jun 6, 2009

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

:dukedog:

Thanks, I've moved the $this->get_exits($sector) out of the loop and put it at the start of the function in a variable called $exits.

Was there something wrong with my loop: for($s = $min; $s <= $distance; $s++) ?

I think I set the value of $min and $distance at the start properly.

edit: Maybe I'll add a count for the exit checking so it won't do an in_array check after there are for exits.

KuruMonkey
Jul 23, 2004

drcru posted:

Was there something wrong with my loop: for($s = $min; $s <= $distance; $s++) ?

No, that example is just my favourite way to explain not recalculating non-varying things in loops.

If get_exits took any appreciable amount of time, that was probably wehere your execution time was getting chewed up. If not, you'll need to get some metrics.

If you need to do that I would:

modify your code above to write to a log when its called, log: what the params were, how many iterations of the inner loop were run, how long the function ran for overall.

Then you can look for what is causing the long executions.

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

:dukedog:

Thanks for the advice. Now if only my VPS were online...

Bitruder
Nov 29, 2003

Majoring in connect the dots and colouring
I need to parse some LaTeX code into human readable code (just a small subset). However, I'm not sure how to use preg_replace (or another suitable tool) to parse something like the following:
code:
\emph{{M}olossus molossus} from {C}uba
... becomes ...
<em><strong>M</strong>olossus molossus</em> from <strong>C</strong>uba
I figure I first need to replace the \emph{blah} with <em>blah</em>, and then do the left over {}'s, but how do I make sure that the } after the M in Molossus doesn't stop preg_replace from matching?

KuruMonkey
Jul 23, 2004
Do you ever have {foo\emph{bar}} or similar?

If not, probably better to do the <strong>s first. Especially if your source only ever has single characters in the <strong>.

Bitruder
Nov 29, 2003

Majoring in connect the dots and colouring
No, it might not be single characters. If I were to do them first, how do I not match \emph{stuff} when I want to just match {stuff}? There might not be white space before the first brace as in my first example.

And yes, {Foo\emph{stuff}} is valid.

Tad Naff
Jul 8, 2004

I told you you'd be sorry buying an emoticon, but no, you were hung over. Well look at you now. It's not catching on at all!
:backtowork:

Bitruder posted:

I need to parse some LaTeX code into human readable code (just a small subset). However, I'm not sure how to use preg_replace (or another suitable tool) to parse something like the following:
code:
\emph{{M}olossus molossus} from {C}uba
... becomes ...
<em><strong>M</strong>olossus molossus</em> from <strong>C</strong>uba
I figure I first need to replace the \emph{blah} with <em>blah</em>, and then do the left over {}'s, but how do I make sure that the } after the M in Molossus doesn't stop preg_replace from matching?

I just noticed the other day that PHP's PCRE has this new "?R" thing which supposedly solves the parenthesis-matching problem, see http://ca2.php.net/manual/en/regexp.reference.php under "recursive patterns".

PHP Manual posted:

Consider the problem of matching a string in parentheses, allowing for unlimited nested parentheses. Without the use of recursion, the best that can be done is to use a pattern that matches up to some fixed depth of nesting. It is not possible to handle an arbitrary nesting depth. Perl 5.6 has provided an experimental facility that allows regular expressions to recurse (among other things). The special item (?R) is provided for the specific case of recursion. This PCRE pattern solves the parentheses problem (assume the PCRE_EXTENDED option is set so that white space is ignored): \( ( (?>[^()]+) | (?R) )* \)

First it matches an opening parenthesis. Then it matches any number of substrings which can either be a sequence of non-parentheses, or a recursive match of the pattern itself (i.e. a correctly parenthesized substring). Finally there is a closing parenthesis.

Haven't tried it yet myself but it sure sounds better than some of the hacks I've done.

indulgenthipster
Mar 16, 2004
Make that a pour over
I found this script for handling file downloads without revealing the path. It works great but once a user uploads a document, its immediatly converted to a random string of letters and numbers. It works for my purposes, however once they download the file I was wondering if there was a way to modify this so that I could name the file whatever I wanted?

So instead of saving the file as 2klsejfwlk2.doc, it would still access that file, but it will save on the users computer as Clean File Name.doc. Is this even possible?

php:
<?
if($_GET['f'] != '') {
    $filename = $_GET['f'];
} else {
    echo 'filename not set';
    exit;
}

$filename = 'path/to/file/'.$filename;

if(ini_get('zlib.output_compression'))
  ini_set('zlib.output_compression', 'Off');

$file_extension = strtolower(substr(strrchr($filename,"."),1));

if( $filename == "" ) 
{
  echo "no filename provided";
  exit;
} elseif ( ! file_exists( $filename ) ) 
{
  echo "file does not exist";
  exit;
};
switch( $file_extension )
{
  case "pdf": $ctype="application/pdf"; break;
  case "exe": $ctype="application/octet-stream"; break;
  case "zip": $ctype="application/zip"; break;
  case "doc": $ctype="application/msword"; break;
  case "xls": $ctype="application/vnd.ms-excel"; break;
  case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
  case "gif": $ctype="image/gif"; break;
  case "png": $ctype="image/png"; break;
  case "jpeg":
  case "jpg": $ctype="image/jpg"; break;
  default: $ctype="application/force-download";
}
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false); // required for certain browsers 
header("Content-Type: $ctype");
header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
readfile("$filename");
exit();
?>

jasonbar
Apr 30, 2005
Apr 29, 2005

VerySolidSnake posted:

I found this script for handling file downloads without revealing the path. It works great but once a user uploads a document, its immediatly converted to a random string of letters and numbers. It works for my purposes, however once they download the file I was wondering if there was a way to modify this so that I could name the file whatever I wanted?

So instead of saving the file as 2klsejfwlk2.doc, it would still access that file, but it will save on the users computer as Clean File Name.doc. Is this even possible?

Replacing
php:
<?
header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
?>
with
php:
<?
header("Content-Disposition: attachment; filename=\"Clean Filename Here." . $file_extension . "\";" );
?>
should work.

jasonbar fucked around with this message at 22:22 on Jun 10, 2009

indulgenthipster
Mar 16, 2004
Make that a pour over

jasonbar posted:

should work.

And it did, thanks!

Safety Shaun
Oct 20, 2004
the INTERNET!!!1
Is there any logical reason why
php:
<?
    function getFileList($directory) 
    {
        $dir = $_SERVER['DOCUMENT_ROOT']."/files/";    
        $results = array();
        $handler = opendir($directory);

        while ($file = readdir($handler))
        {
            if ($file != '.' && $file != '..')
            {
                $fullpath = $dir . $file;
                $results[]["filename"] = $file;
                $results[]["writetime"] = filemtime($fullpath);
                $results[]["size"] = filesize($fullpath);
            }
        }

        closedir($handler);
        return $results;

    }

    $dir = $_SERVER['DOCUMENT_ROOT']."/files/";
    $results = getFileList($dir);
        
    foreach ($results as $value)
    {
        $filename = $value["filename"];
        $writetime = $value["writetime"];
        $filesize = $value["size"];
        
        echo "$filename time:$writetime size:$filesize <br>";
    }
?>
is spitting out this exact formatting:
code:
Windows7Screenshot2.png time: size:
time:1241826449 size:
time: size:1805257
20090610_L_Hai.jpg time: size:
time:1244660004 size:
time: size:78007
Here.jpg time: size:
time:1241826333 size:
time: size:95370
Rainbow Books.txt time: size:
time:1241826915 size:
time: size:341
Windows7Screenshot.png time: size:
time:1241826406 size:
time: size:693221
walk.png time: size:
time:1242253484 size:
time: size:1245853
DataSorting.cs.txt time: size:
time:1241826325 size:
time: size:6219 

Supervillin
Feb 6, 2005

Pillbug

Safety Shaun posted:

Is there any logical reason why
php:
<?
...
                $results[]["filename"] = $file;
                $results[]["writetime"] = filemtime($fullpath);
                $results[]["size"] = filesize($fullpath);


$results[] assigns the value to the next index in the $results array, even if you're actually storing something in a subarray. So basically you're doing this:

php:
<?
$results[0]["filename"] = $file;
$results[1]["writetime"] = filemtime($fullpath);
$results[2]["size"] = filesize($fullpath);
?>
Then the next loop assigns indexes 3, 4, and 5, and so on. Define a counter, increment it in the loop, and use that as the explicit index.

Edit: vvv Nope, not a huge rewrite. Glad it worked for ya, Safety Shaun. The = array(...) solution would also work fine in case you prefer that.

Supervillin fucked around with this message at 16:36 on Jun 12, 2009

KuruMonkey
Jul 23, 2004
Doesn't need that huge a rewrite, do this:

php:
<?
$results[] = array(
   "filename" => $file,
   "writetime" => filemtime($fullpath),
   "size" => filesize($fullpath)
);
?>
Think of $array[] as "new cell" - each time you use it you will create a new cell in the array, at the end. So you just need to package up what you're adding to the array before you add it.

Edit: Safety Shaun you might want to cast an eye at stat() too.

KuruMonkey fucked around with this message at 08:34 on Jun 12, 2009

Adbot
ADBOT LOVES YOU

Safety Shaun
Oct 20, 2004
the INTERNET!!!1

Supervillin posted:

$results[] assigns the value to the next index in the $results array, even if you're actually storing something in a subarray.

Thanks Supervillin, all sorted.

php:
<?
        $currentfile = 0;
        
        while ($file = readdir($handler))
        {
            if ($file != '.' && $file != '..')
            {
                $fullpath = $dir . $file;
                $results[$currentfile]["filename"] = $file;
                $results[$currentfile]["writetime"] = filemtime($fullpath);
                $results[$currentfile]["size"] = filesize($fullpath);
                $currentfile++;
            }
        }
?>

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