# [Solved] Perl won't recognize my initialized variable - ??



## Auroralei (Jun 11, 2004)

I am attempting to write a program that will pull an image from a file (through a MySQL database) and display it based on a keyword match from a form on a web page.

Please look at my program below (an abbreviated version). See that I specify in the header that the length is the length of $data (the filehandle) and then print $data.

Examples that I've looked at tell me that I should use a $data variable, which is initialized at the beginning, as the variable that contains the image. Perl keeps trying to tell me that I'm using an uninitialized variable, and won't run the script.

Can anyone help me?

Many thanks.

#! /usr/bin/perl -w

use strict;
use lib qw(C:/Perl/lib);
use CGI qwstandard escapeHTML);
use FileHandle;
use trial_image_db;

my $image_dir = "C:/Documents and Settings/Owner/My Documents/My Pictures/Database Print-Ready 8x8/Finished Pr/BPFPR";
my $path_sep = "/";

my $name;
my $data;

my $keyword = param ("keyword");
my $type = "image/jpeg";

my $fh = new FileHandle;

my $dbh = trial_image_db::connect ();

if (defined ($keyword) && $keyword !~ /^\s*$/)

{
$name = $dbh->selectrow_array (
"SELECT name FROM keywords WHERE keyword01 = ? ORDER BY rand", undef, $keyword)
or error ("No matching image for keyword $keyword");

my $image_path = $image_dir . $path_sep . $name;
open ($fh, $image_path) or error ("Cannot read $image_path: $!");

binmode ($fh);
my $size = (stat ($fh))[7];

read ($fh, $data, $size) == $size or error ("Failed to read entire file $image_path: $!");
$fh->close ();
}

$dbh->disconnect ();

print header (-type => $type, -Content_Length => length ($data));
print ($data);

exit (0);


----------



## Shadow2531 (Apr 30, 2001)

delete the "my $data" line. (you may have to do the same for the "my $name" line too)

$data is already declared. You do not need to declare it again or you'll just cause $data to uninitialize.

Since you uninitialized it when you redeclared it, you get the not initialized error because you didn't make $data = anything.

That looks like the problem to me.

However, if you del the "My $data" line, it might throw a different error. If it does, then put it back and make it my $data = "" and see if everything works.

If you are opening a file with

open(FD, "filename") ;

, you'll want to initialize $data like this instead

my $data = <FD>;

Then you can get the length of $data.

Hope that helps.


----------



## Auroralei (Jun 11, 2004)

Thanks Shadow,

That worked -- it has no problem with the variable now, but when I run the program, it doesn't return any images. I'm using a form on a web page that points to the .pl program in my cgi-bin, and an <img> tag that points to the same program.

When I enter in a keyword, I see the command prompt flash up briefly, and then -- nothing. The webpage doesn't register it at all -- no error message, nothing.

Do you know what could be wrong?

Many thanks,
L


----------



## Auroralei (Jun 11, 2004)

When I run this script using a form that points to this .pl file and an <img> tag that points to the same file, I get nothing back. I see the command prompt flash briefly, but no error message or anything.

Can anyone see what may be wrong with this script? I have tried countless variations.

#! /usr/bin/perl -w

use strict;
use lib qw(C:/Perl/lib);
use CGI qwstandard escapeHTML);
use FileHandle;
use trial_image_db;

my $image_dir = "C:/Apache/Apache2/htdocs/BPFPR";
my $path_sep = "/";

my $name;

my $keyword = param ("keyword");
my $type = "image/jpeg";

my $fh = new FileHandle;
my $data = "";

my $dbh = trial_image_db::connect ();

if (defined ($keyword) && $keyword !~ /^\s*$/)

{
$name = $dbh->selectrow_array (
"SELECT name FROM keywords WHERE keyword01 = ? ORDER BY rand", undef, $keyword)
or error ("No matching image for keyword $keyword");

my $image_path = $image_dir . $path_sep . $name;
open ($fh, $image_path) or error ("Cannot read $image_path: $!");

binmode ($fh);
my $size = (stat ($fh))[7];

read ($fh, $data, $size) == $size or error ("Failed to read entire file $image_path: $!");
$fh->close ();

}

$dbh->disconnect ();

print header (-type => $type, -Content_Length => length ($data));
print ($data);

exit (0);


----------



## Shadow2531 (Apr 30, 2001)

Which one of the suggestions did the trick with the variable?

Do you have it set up like kind of like this?

http://www.yoursite.com/cgi-bin/file.pl?keyword=pic1.jpg

If you can zip up everything that is needed to work, I can try it myself to see what's going on.

If everything needs to be kept private, create a non-private example that we can try.

Or at least repost your code as it is now.


----------



## Shadow2531 (Apr 30, 2001)

http://forums.techguy.org/t237784.html

O.K. Now that I see this thread, I think it's still the data line.

Using my $data = ""; got rid of the error, but I think that makes $data = nothing.

I think you need to do something like this.

When keyword=5, your code needs to load

open(FD, "C:/Apache/Apache2/htdocs/BPFPR/5.jpg") ;
Then make make my $data = <FD>;

Then you can get the size of $data and adventually load










I'll try to make an example for you that should work.


----------



## Flrman1 (Jul 26, 2002)

I have merged your two threads. Please stick with one thread.


----------



## Auroralei (Jun 11, 2004)

Thanks Shadow!

You'll notice that I'm using the FileHandle module which allows a 'NewHandle' rather than FD -- I've tried subbing in FD but when I do, Perl tells me that I'm trying to read from an unopened filehandle on the my $data=<FD> line.

Instead, I've tried my $data = <$fh>, which raises no objections for the $data variable, but now Perl is telling me that 'global symbol $dbh requires explicit package name' on lines 20, 25 and 42!!

I liked your example, but keep in mind that the keywords are not the same as the filename (I'm only solving for keyword 1 right now in order to keep this simpler).

Thanks so much,
Laura


----------



## Auroralei (Jun 11, 2004)

Hi again, I just saw your 1st post -- I would love to zip up everything and send it to you. What about the SQL database table though? How do I send that?

It would be a file of 12 images, a mySQL table with names and keywords of 12 images, the .pl file, and a dbh file with a username and password.

Does that sound right? 

Laura


----------



## Shadow2531 (Apr 30, 2001)

You got a pm.

Anyway, for the database part, I think you would have to zip up and send your C:\mysql\data\trial_image folder. (on windoze at least)

If you want, you can just setup a smaller database that only includes the keyword for one image and just send that one image.

Just need enough to play with to better get the picture of what's goin on.


----------



## Shadow2531 (Apr 30, 2001)

Nevermind on sending me the stuff. I created my own database etc.

Here's the working code I have.


```
#! /usr/bin/perl

use strict;
use lib qw(C:/Perl/lib);
use CGI qw(:standard escapeHTML);
use FileHandle;
use DBI;
use Mysql;
my $image_dir = "C:/Apache2/htdocs";
my $path_sep = "/";

my $keyword = param ("keyword");
my $type = "image/jpeg";

my $fh = new FileHandle;
my $data = "";
my $host = '127.0.0.1';
my $db = 'keywords';
my $db_user = '';
my $db_password = '';
my $dbh = DBI->connect("dbi:mysql:$db:$host", "$db_user", "$db_password");

if (defined ($keyword) && $keyword !~ /^\s*$/)

{
my $name = $dbh->selectrow_array ("SELECT file FROM keywords WHERE keyword = ? ORDER BY keyword", undef, $keyword) or error ("No matching image for keyword $keyword");

my $image_path = $image_dir . $path_sep . $name;
open ($fh, $image_path) or error ("Cannot read $image_path: $!");

binmode ($fh);
my $size = (stat ($fh))[7];

read ($fh, $data, $size) == $size or error ("Failed to read entire file $image_path: $!");
$fh->close ();

}

$dbh->disconnect ();

print header (-type => $type, -Content_Length => length ($data));
print ($data);

exit (0);
```
FYI: htdocs for me is installed at c:\apache2\htdocs

mysql is installed to default.

Attached is the table code to create the keywords database that I used.

In c:\apache2\htdocs , I have 2 pics. 5.jpg and 6.jpg

For perl, I had to run ppm install DBI and ppm install dbd-mysql.

I named the file data.pl and it is in c:\apache2\cgi-bin

in c:\apache2\htdocs , I have pic.html which has the following code.


```
<img src="http://127.0.0.1/cgi-bin/data.pl?keyword=test" alt="" />
```
That loads pic 5.jpg

The other keyword in the database is test2, which loads 6.jpg

You can also directly load /cgi-bin/data.pl?keyword=test to have it load the 5.jpg

I had to modify your select_array line to work with what I had.

Hope that helps.

BTW, the username and password variables might have to be kept blank like they are in the code. They needed to be blank for me.

To get everything working, I had to keep checking the error.log in apache, so if you get any errors, check there.

That's my first time ever working with a database, so the code might not be 100% proper, but it works right. (although I think the select_array line might not be perfect)

Others should should give it a look-see.

Notes: If you load data.pl directly without a keyword, it will show an image place holder. If you load data.pl with a keyword that is not in the database, you'll get an internal server error. So you will have to add a little bit of error handle just to make things perfect in case someone typed the address to data.pl in the address bar without any keywords or an invalid keyword.


----------



## Auroralei (Jun 11, 2004)

Wow, thank you so much!

Well I used your script and recreated the conditions exactly on my server, and I get exactly the same thing happening as with my original, which leads me to suspect that I have my server set up incorrectly.

My error log says

[Mon Jun 14 15:11:33 2004] [error] [client 127.0.0.1] (OS 3)The system cannot find the path specified. : couldn't create child process: 720003: shadowtrial.pl
[Mon Jun 14 15:11:33 2004] [error] [client 127.0.0.1] (OS 3)The system cannot find the path specified. : couldn't spawn child process: C:/Apache/Apache2/cgi-bin/shadowtrial.pl

(I renamed your script and altered the img tag accordingly).

But it's there!

I also can't get my server to find php scripts, btw -- it says File does not Exist in the error log.

I have configured my conf httpd file to accept cgi scripts, (ScriptAlias /cgi-bin/ "C:/Apache/Apache2/cgi-bin/") and have included the .pl extension as a PATHEXT in the environment variable. I have tried configuring apache for php both as a module and as embedded binary.

If you have any suggestions, I would love to hear them.

Laura


----------



## Shadow2531 (Apr 30, 2001)

Here are my notes on how I setup apache, perl, python, php and mysql on Windows.

They may help.

http://home.tbbs.net/shadow/hardforums/apache2.txt


----------



## Auroralei (Jun 11, 2004)

Thanks so much, your information has been invaluable.

I accidentally deleted your pm and never got to read it. Please resend if you still have it.

However, I did use your notes -- I have uninstalled and reinstalled everything exactly as specified in them. I have one thing left to do and that's add the directories into my PATH (the last thing on your list) -- but I don't understand how to do this. Where do I enter that information? On the command line? 

Hopefully this will represent the last of my config problems. Whew!

L


----------



## Shadow2531 (Apr 30, 2001)

If you have winXP/Win2K, you

right-click on "My Computer"
Left-click on "properties"
left-click "advanced" tab
left-click "Enviroment Variables" button
Under "System Variables" is the "Path" variable.
Add to that. If you installed ActivePerl, it should already be in there. You'll probably only have to add python. (and php if you want).

For Win9x, you can temporarily set it at the command line, or put the command in the autoexec.bat file.

To add to the path in the autoexec.bat for win98 I think you do it like this

set PATH=%PATH%;c:\perl\bin

Basically that sets the path to the current path and then adds c:\perl\bin to it.

So if you are adding to the path, you'll always want to have at least

set PATH=%PATH% or you might erase all the existing entries; meaning you wouldn't want to do

set PATH=c:\perl\bin


----------



## Auroralei (Jun 11, 2004)

Okay, just one last thing:

Do I need MinGW, GTK and Nasm in order for everything to work properly? I don't seem to have them -- should I download them? 

And Python. I already downloaded php -- should I have Python too?

And, if I don't need these things, should I take them out of the PATH, or does it not matter if there are extra directories in there?

L


----------



## Shadow2531 (Apr 30, 2001)

You don't need nasm, python and mingw etc,. That was just an example of my path. You can remove those from the path if you don't have them. Just make sure perl is in the path. 

I'll check to see if your task is easier to do in python/php/c++ just for curiousity.


----------



## Auroralei (Jun 11, 2004)

Okay. I set up the programs, and in my brower window I entered:

http://localhost/C:/Apache2/cgi-bin/shadowtrial.pl

Is that right?

But what I'm getting in the window is a message saying "You are not authorized to view this page". I changed the script to contain my MySQL name and password but I get the same thing. Is it part of my apache setup that I need to change, do you think?

L


----------



## Shadow2531 (Apr 30, 2001)

No that's not right.

Use

http://localhost/cgi-bin/shadowtrial.pl

or

http://127.0.0.1/cgi-bin/shadowtrial.pl


----------



## Shadow2531 (Apr 30, 2001)

BTW, I tried the script you sent me. I tried it out before modifying it. I get no errors and it works like it's supposed to.

However it works for me because the select_array line is still set for my database. I'll need to see yours to see how to set it up.


----------

