gayu_justin has asked for the wisdom of the Perl Monks concerning the following question:

In my template file, i have written the code like below

[% IF cnt > 0 %] <tr><td colspan="2"> <h3 align="center">Have + you verified the Checklist ?</h3></td></tr> [%- SET i = 0; WHILE i < checklists.size; -%] <tr> <td> <input type="checkbox" name="chec +k_[% check_id.$i %]" value="1"/> </td> <td> [% checklists.$i %] </td> </tr> [%- SET i = i + 1; END -%]

And i want to take the name of the checklist in the cgi page, so that the value can be inserted into the database.since the name of the checklist has been given inside the array, i can't take that individually, so inthe cgi page, i have used the code like this :

if( $user->id){ my $usr = $user->id; my @userchecklist_id; my $check_ = "chck"; my $chck_ = "check"; my $quer = "SELECT checklist.id FROM group_management,User_group_manag +ement_mapping,profiles,checklist,checklist_group_mapping WHERE User_g +roup_management_mapping.userid = $usr and profiles.userid = User_gro +up_management_mapping.userid and group_management.id =User_group_mana +gement_mapping.groupid and checklist_group_mapping.checklist_id = che +cklist.id and checklist_group_mapping.group_id = group_management.id" +; my $query = $dbh -> prepare($quer); $query-> execute(); while(my($usrcheck_id) = $query->fetchrow_array()) { push (@userchecklist_id,$usrcheck_id); } foreach $usr( @userchecklist_id) { #print $usr . "\n"; #print $check_.$usr; my $check_.$usr = $cgi->param("$chck_.$usr"); print $chck_.$usr; } }
It is showing the error in the line my $check_.$usr = $cgi->param("$chck_.$usr");

only if i can take the name of the checkbox, i can insert the value into the database. How can i achieve this.??

Note : @userchecklist_id contains values same as that % check_id.$i %, used in the template file.

Replies are listed 'Best First'.
Re: showing the error ,Can't modify concatenation (.) or string in scalar assignment
by marto (Cardinal) on Jul 18, 2013 at 09:32 UTC

    As a side note you are making a mistake with this SQL query. Take a quick look at Exploits of a mom, SQL_injection. The DBI documetation has a section on Placeholders and bind variables, and links to references about SQL injection also Bobby Tables -> Perl.

    Your code:

    my $quer = "SELECT checklist.id FROM group_management,User_group_manag +ement_mapping,profiles,checklist,checklist_group_mapping WHERE User_g +roup_management_mapping.userid = $usr and profiles.userid = User_gro +up_management_mapping.userid and group_management.id =User_group_mana +gement_mapping.groupid and checklist_group_mapping.checklist_id = che +cklist.id and checklist_group_mapping.group_id = group_management.id" +; my $query = $dbh -> prepare($quer); $query-> execute();

    Becomes:

    my $SQLquery = " SELECT checklist.id FROM group_management, User_group_management_mapping, profiles, ch +ecklist,checklist_group_mapping WHERE User_group_management_mapping.userid = ? and profiles.userid = User_group_management_mapping.userid and group_management.id = User_group_management_mapping.groupid and checklist_group_mapping.checklist_id = checklist.id and checklist_group_mapping.group_id = group_management.id"; my $sth = $dbh->prepare( $SQLquery ); $sth->execute( $usr );

    Note that I've changed some of the variable names you used, and made it a little easier to read IMHO.

Re: showing the error ,Can't modify concatenation (.) or string in scalar assignment
by hdb (Monsignor) on Jul 18, 2013 at 09:24 UTC

    On the left hand side of your assignment

    my $check_.$usr = $cgi->param("$chck_.$usr");

    you do not have an item that something can be assigned to as it is the concatenation of two strings. You need to define a new variable for that purpose, eg

    my $check_usr = $cgi->param("$chck_.$usr");
Re: showing the error ,Can't modify concatenation (.) or string in scalar assignment
by kcott (Archbishop) on Jul 18, 2013 at 10:03 UTC

    G'day gayu_justin,

    Firstly, this code is highly confusing and a potential source of errors:

    my $check_ = "chck"; my $chck_ = "check";

    Regarding the code generating the error, instead of:

    foreach $usr( @ #print $usr . "\n"; #print $check_.$usr; my $check_.$usr = $cgi->param("$chck_.$usr"); print $chck_.$usr; }

    I suspect you want something closer to this (untested):

    for my $user_id (@userchecklist_id) { my $checkbox_name = "check_$user_id"; my $checkbox_value = $cgi->param($checkbox_name); print "Checkbox name: $checkbox_name\n"; print "Checkbox value: $checkbox_value\n"; }

    By using meaningful variable names and taking a little care when laying out your code, you'll improve readability and maintainability. Take a look at perlstyle for some tips on the latter.

    As a final point, note how you've reused $usr:

    my $usr = $user->id; ... foreach $usr( @userchecklist_id) {

    This, again, is a potential source of errors. Consider what might happen if you wanted to use the $user->id version of $usr after the loop. By using my when you start the loop (as I did) you get a different variable (scoped to the loop) and avoid possible future problems. [In case you didn't know, for and foreach are synonymous so you can save yourself some typing (see perlsyn - Foreach Loops).]

    -- Ken

      The following is more for the benefit gayu_justin than for kcott:

      Consider what might happen if you wanted to use the $user->id version of $usr after the loop. By using my when you start the loop (as I did) you get a different variable (scoped to the loop) and avoid possible future problems.

      This is an oddity, IMHO, of the way for-loop variables behave. The variable is fully localized even though it is lexical. So this code doesn't work as one (I myself, on more than one occasion) would naively expect:

      >perl -wMstrict -le "my $max_x = 99; ;; for $max_x (0 .. 5) { print $max_x; last if $max_x == 2; } ;; print qq{max_x: $max_x}; " 0 1 2 max_x: 99

      Nor does the loop variable do something really odd like becoming a package variable:

      >perl -wMstrict -le "my $x = 'foo'; print qq{x before loop: '$x'}; ;; for $x (0 .. 2) { func(); our $y; print qq{$x, $y}; } ;; print qq{x after loop: '$x'}; sub func { our $x; our $y; $x = 99; $y = 42; } " x before loop: 'foo' 0, 42 1, 42 2, 42 x after loop: 'foo'

      So what's the point of ever using a lexical loop variable in the  for my $x (...) { ... } form? If  $x was a package variable to start with, the loop variable  $x would then be fully lexically scoped. Remove the  my from the following example to see the difference.

      >perl -wMstrict -le "our $max_x = 99; ;; for my $max_x (0 .. 4) { func(); print $max_x; last if $max_x == 2; } ;; print qq{max_x after loop: $max_x}; ;; sub func { $max_x = 42; } " 0 1 2 max_x after loop: 42

        ++ You're absolutely right. I've been writing for my $var ... for so long that I'd forgotten about that rather unintuitive behaviour.

        By the way, you're not the only one to have been bitten by that. :-)

        -- Ken

Re: showing the error ,Can't modify concatenation (.) or string in scalar assignment
by gayu_justin (Novice) on Jul 18, 2013 at 09:48 UTC

    i have changed the code to , my $check_usr = $cgi->param("$chck_.$usr"); but after checking the checkbox and on printing it is not showing any value. what may be reason???

      Probably because there's no CGI parameter called "check.whatever". You need to get rid of the dot, and then learn how variables interpolate in strings. Read perldata.