Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

review my code? (newbie here)

Status
Not open for further replies.

pkirill

Technical User
Jun 15, 2002
134
US
With much help and lots of searching I've been able to bring together the code below. It consists of two PHP files and one text file. MUSICLIST.PHP reads the text file and displays a table for the viewer where they can select songs by checking the associated box. Then they click submit and the selected songs are displayed and a list is emailed to me.

The *problem* is that it works when less that about 45-50 songs are selected - there are over 900 in the text file. Any more than that and the Submit button seems to quit working - click it and nothing happens. I know I should probably be using MySQL or something, but a)that's out of my range and b) there is no db available on the hosting site...

Any help in getting this to work would be greatly appreciated. Thanks in advance!

Code:
[b]MUSICLIST.PHP[/b]
<html>
<body>
<form action="musicsend.php">
<table border="1">
<tr><th>I want it</th><th>Title</th><th>Artist</th></tr>
<?php
$FIL=fopen("music.txt","r");
while ($lin=fgetcsv($FIL,100000,",")) {
  echo "<tr><td><input type=\"checkbox\" name=\"nr[]\" value=\"$lin[0]\"></td><td>$lin[0]</td><td>$lin[1]</td></tr>\n";
}
fclose($FIL);
?>
</table>    
<input type="submit" value="Send selection list">
</form>
</body>
</html> 

[b]MUSICSEND.PHP[/b]
<html>
<body>
<?php
$lis=$_GET[nr];
$mess="Prepare the following files : ";
echo "You sent a list of ",count($lis)," melodies :<br>\n";
if ($lis) {
  echo "<ol>\n";
  $FIL=fopen("music.txt","r");
  while ($lin=fgetcsv($FIL,10000000,",")) if (array_search($lin[0],$lis)!==false) {
    echo "<li>$lin[0] - $lin[1]</li>\n";
    $mess.="\n$lin[0],$lin[1],$lin[2],$lin[3]";
  }
  fclose($FIL);
  echo "</ol>\n";
  mail("email@yourdomain.com","Playlist requirement:",$mess);

}
?>
</body>
</html>

[b]MUSIC.TXT[/b] (this is just a sample list)
1999,PRINCE,CD title,Track #
#1 (RADIO EDIT),NELLY,CD title,Track #
(SITTIN' ON) THE DOCK OF THE BAY,OTIS REDDING,CD title,Track #
'03 BONNIE & CLYDE,"JAY-Z, BEYONCE",CD title,Track #
100 YEARS,FIVE FOR FIGHTING,CD title,Track #
100  PURE LOVE,CRYSTAL WATERS,CD title,Track #
19 SOMETHIN ',MARK WILLS,CD title,Track #
A MOMENT Like THIS,KELLY CLARKSON,CD title,Track #
A PIRATE LOOKS AT FORTY,JIMMY BUFFETT,CD title,Track #
A PROMISE OF LOVE (INSTRUMENTAL),JOHN TESH,CD title,Track #
A SORTA FAIRYTALE,TORI AMOS,CD title,Track #
A THOUSAND MILES,VANESSA CARLTON,CD title,Track #
A WOMAN 'S WORTH,ALICIA KEYS,CD title,Track #
 
It could be any of a number of things.

Perhaps the script is timing out.
Perhaps since you have not set the "method" attribute of your <FORM> tag, your browser is trying to send the data on the URL (GET method) and the URL is getting too long.



Want the best answers? Ask the best questions! TANSTAAFL!
 
Code:
echo "You sent a list of ",count($lis)," melodies :<br>\n";

should not the commas here be concatenators (dots)?

this has nothing to do with why your code is not working (on which topic i agree with sleipnir214 that the querystring might be too long (IE = 2083 chars) although i am surprised that 50 songs would do it:

say average song title = 15 chars
prepend &nr[]= = 5 chars
total 20 chars
50 songs = 1000 chars

firefox has a longer url max-out: does the same problem occur?

you also might want to use in_array() rather than array_search() as it does not appear that you need the key returned

nearly lastly the manual recommends using f_get_csv like this (ie with an explicit type comparison)
Code:
while ( ($lin=fgetcsv($FIL,10000000,",")) !== FALSE) {
    if (array_search($lin[0],$lis)!==false) {
      echo "<li>$lin[0] - $lin[1]</li>\n";
      $mess.="\n$lin[0],$lin[1],$lin[2],$lin[3]";
    }
}

and lastly ... it's not a good idea to build any type of database (and a flat file is a database) without a unique key. song titles are hardly unique (as in 1985 i recall selecting the "power of love" on a juke box and getting jennifer rush rather than huey lewis [long time ago] who were in the carts at the same time with the same song name). why not attach a unique number as the first data point in each line and the use that as the value attribute of your checkboxes?

 
I'd go with sleipnir214 and not setting the method, I tested the code ad was surprised to find musicsend.php being downloaded by my browser instead of being parsed, when i hit the submit button.


______________________________________________________________________
There's no present like the time, they say. - Henry's Cat.
 
this piqued my interest (get vs post and that i couldn't find any definitive resources on firefox). i used this code and selected all of the checkboxes. the code failed every time using the get method but was find on post.

i'm going to write some code to determine when the failure takes place. i will post back if i get a definitive result.

Code:
<?
//establish the test file
$filename = "test.csv";
if (!file_exists($filename)):
	$fh=fopen($filename, "wt");
	for ($i=0; $i<1000; $i++):
		fputcsv($fh, array("Song Title $i", "Artist for Song $i"));		
	endfor;
	fclose($fh);
endif;
// end test file

if (isset($_POST['nr'])):
	parseResult();
else:
	showForm();
endif;

function parseResult() {
	global $filename;
	$fh = fopen($filename, "rt");
	$list = $_POST['nr'];
	$results = "";
	$cnt = 0;
	while ( ($songData = fgetcsv($fh)) !== FALSE):
		if (in_array($songData[0], $list)):
			$results .= "<tr><td>{$songData[0]}</td><td>{$songData[1]}</td></tr>";
			$cnt++;
		endif;
	endwhile;
	echo "Number of songs requested: $cnt <br/>";
	echo <<<STR
<table border="1">
<tr><th>Song Title</th><th>Song Artist</th></tr>
{$results}
</table>
STR;
	fclose ($fh);
	echo "<div><a href=\"{$_SERVER['PHP_SELF']}\">Click here to go back to the choices</a></div>";
}
function showForm() {
	global $filename;
	$fh = fopen($filename, "rt");
	echo <<<STR
<form method="post" action="{$_SERVER['PHP_SELF']}">
<table border="1">
<tr>
	<th>
		<input 	type="checkbox" 
				onClick="
						for (i=0; i<this.form.elements.length; i++) {
							if (this.form.elements[i].name == 'nr[]'){
								this.form.elements[i].checked = this.checked;
							}
						};"
		/>
		Check All
	</th>
	<th>
		Song Title
	</th>
	<th>
		Song Artist
	</th>
</tr>
STR;
	while ( ($songData = fgetcsv($fh)) !== FALSE):
		echo  <<<STR
<tr>
	<td>
		<input 	type="checkbox"
				name="nr[]"
				value="{$songData[0]}"
		/>
	</td>
	<td>
		{$songData[0]}
	</td>
	<td>
		{$songData[1]}
	</td>
</tr>

STR;
	endwhile;
	echo "</table><input type=\"submit\" name=\"submit\" value=\"submit\"/></form>";
}
?>
 
some experimentation shows that the ie7 url string maxes out at about 2084 and firefox at about 5954.. "about" because the code i used was really quite rough.

Code:
<?
$url = "[URL unfurl="true"]http://localhost/tmogolf/qfinance/Untitled-1.php?"[/URL] . $_SERVER['QUERY_STRING'] . "&u[]=";
$fh = fopen("firefoxtest.txt", "wt");
fwrite ($fh, strlen($url));
fclose ($fh);
?>
<script>
window.onload = function() {
	window.location.href = "<?=$url?>";
}
</script>
 
Since GET-method input is handed to a CGI program via an environment variable, you can have web-server OS-specific limits to those values, too.



Want the best answers? Ask the best questions! TANSTAAFL!
 
Thanks to everyone! It turns out that it was a get vs. post.

changing this line in musiclist.php:
Code:
<form action="musicsend.php" method="post">

and this line in musicsend.php:
Code:
$lis=$_POST[nr];
solved the problem!

Thanks again! (oh, and these fixes were provided by feherke in the Web Design forum...)
 
Since GET-method input is handed to a CGI program via an environment variable, you can have web-server OS-specific limits to those values, too.

that's interesting. thanks. i've never got into the meat of what the webserver does before directing input to php. on the list of things to learn about... [looong list]
 
Yeah, GET-method input goes to a CGI via an environment variable and POST goes in through stdin.

I helped write a special-purpose web server once, and had to get much deeper into the HTTP and CGI specs than I ever thought I had to.



Want the best answers? Ask the best questions! TANSTAAFL!
 
I posted the "GET" versus "POST" observation to this thread 4 hours ago.

And that's the trouble with geniuses - they don't know how to dumb it down for rest of us. Your "observation" wasn't an answer I could understand as PHP-layperson. But it's the thought that counts and I appreciated it.

And I didn't cross post. I originally posted in the Design forum because I was hoping someone had run across a ready-made program I had missed in all my searching. feherke was kind enough to post a complete solution (almost). In thanking him, I remarked there was slight hiccup in the code and that I would follow up in this forum - which I understand to be the correct forum to discuss PHP code issues. In the mean time, he posted the get/post code corrections in the other forum...
 
Ah-ha, so what you were actually saying was that sleipnir214 did not spoon feed you the complete solution. Checking back, you're right. His reply only said that you're probably using get method, which could fail if there's too many things being sent. It is a very very difficult to understand statement -- without in-depth knowledge of php, you could not know what he was talking about.
 
But thank goodness we have our new forum MVP for when thinking is just too hard ;)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top