Php Notice: Use of undefined constant - constants

What am i doing wrong ?
echo try_add("test","2562782");
echo try_add("test","25627826");
function try_add($ct,$tankid){
$file = 'testFile_'.$ct.'.txt';
$pizza = file_get_contents($file);
preg_match_all("/Tankid:(?P.*?);/", $pizza, $pie);
//print_r($pie);
//outputs
//Array
//(
// [0] => Array
// (
// [0] => Tankid:2562782;
// [1] => Tankid:25627826;
// [2] => Tankid:2562782;
// [3] => Tankid:25627826;
// )
//
// [this] => Array
// (
// [0] => 2562782
// [1] => 25627826
// [2] => 2562782
// [3] => 25627826
// )
//
// [1] => Array
// (
// [0] => 2562782
// [1] => 25627826
// [2] => 2562782
// [3] => 25627826
// )
//
//)
foreach($pie[this] as $thi){
if($thi == $tankid){
$inthis = "yes";
}
else{
$inthis = "no";
}
}
if($inthis == "no"){
$myFile = "testFile_$ct.txt";
$fh = fopen($myFile, 'a');
$stringData = "Tankid:$tankid;\n";
fwrite($fh, $stringData);
fclose($fh);
return "This '$tankid' has been added in this file '$myFile' \n";
}
else{
return "This '$tankid' is already in this file '$myFile' \n";
}
}
//Code outputs
//Notice: Use of undefined constant this - assumed 'this' in \xampp\htdocs\new.php on line 39
//This '2562782' has been added in this file 'testFile_test.txt'
//Notice: Use of undefined constant this - assumed 'this' in \xampp\htdocs\new.php on line 39
//This '25627826' has been added in this file 'testFile_test.txt'

Change
foreach($pie[this] as $thi){
Into
foreach($pie['this'] as $thi){

You just need to rewrite
foreach($pie[this] as $thi){
into
foreach($pie[$this] as $thi){
You could even use
foreach($pie as $thi){

Related

How in php8 make match with more complicated conditions?

As php8 allows match like :
echo match ($v) {
0 => 'Foo',
1 => 'Bar',
2 => 'Baz',
}; // Bar
I wonder if there is a way to use in match more complicated conditions, like :
if ($checkValueType == EnumType::Integer and ! isValidInteger($value) and ! empty
($default_value)) {
return $default_value;
}
if ($checkValueType == EnumType::Float and ! isValidFloat($value) and ! empty($default_value)) {
return $default_value;
}
if ($checkValueType == EnumType::Bool and ! isValidBool($value) and ! empty($default_value)) {
return $default_value;
}
return $value;
Thanks in advance!
No, you can't do that, because match is an expression, and cannot contain statements.
Structure of a match expression
$return_value = match (subject_expression) {
single_conditional_expression => return_expression,
conditional_expression1, conditional_expression2 => return_expression,
};

Update hash indexed keys separately with a for loop

I have a %parallel_hash with indexed key names 0-2:
%parallel_hash
(function_name_0 => "sharp_mpi_steps::run_mpirun",
params_name_0 => ("reporter","xml_obj",$hash{value}),
function_name_1 => "sharp_mpi_steps::run_mpirun",
params_name_1 => ("reporter","xml_obj",$hash{value}),
(function_name_2 => "sharp_mpi_steps::run_mpirun",
params_name_2 => ("reporter","xml_obj",$hash{value})
I would like to update the $hash{value} content with an indexed text. To each $hash{value} inside params_name_$i, simply add another key and value: reporter_message => "process_$i"
my code is:
package delete;
use strict;
use warnings FATAL => 'all';
my %parallel_hash;
my %hash_mpi;
$hash_mpi{value}->{bind_to} = "none";
for (my $i=0;$i<=2;$i++)
{
my %hash;
$hash{value} = $hash_mpi{value};
$parallel_hash{"function_name_$i"} = "sharp_mpi_steps::run_mpirun";
#{$parallel_hash{"params_name_$i"}} = ("reporter","xml_obj",$hash{value});
$parallel_hash{"params_name_$i"}->[2]->{reporter_message} = "process_$i";
}
print ("Done");
1;
I would like to get:
%parallel_hash
'function_name_0' = "sharp_mpi_steps::run_mpirun"
'params_name_0' =
[0] = "reporter"
[1] = "xml_obj"
[2] =
'bind_to' = "none"
'reporter_message" = "process_0"
'function_name_1' = "sharp_mpi_steps::run_mpirun"
'params_name_1' =
[0] = "reporter"
[1] = "xml_obj"
[2] =
'bind_to' = "none"
'reporter_message" = "process_1"
'function_name_2' = "sharp_mpi_steps::run_mpirun"
'params_name_2' =
[0] = "reporter"
[1] = "xml_obj"
[2] =
'bind_to' = "none"
'reporter_message" = "process_2"
The problem is that after the "reporter_message" key is added, it updates all the previous "params_name_$i" as well:
%parallel_hash
'function_name_0' = "sharp_mpi_steps::run_mpirun"
'params_name_0' =
[0] = "reporter"
[1] = "xml_obj"
[2] =
'bind_to' = "none"
'reporter_message" = "process_2"
'function_name_1' = "sharp_mpi_steps::run_mpirun"
'params_name_1' =
[0] = "reporter"
[1] = "xml_obj"
[2] =
'bind_to' = "none"
'reporter_message" = "process_2"
'function_name_2' = "sharp_mpi_steps::run_mpirun"
'params_name_2' =
[0] = "reporter"
[1] = "xml_obj"
[2] =
'bind_to' = "none"
'reporter_message" = "process_2"
How can I avoid this updating?
my %hash_mpi;
$hash_mpi{value}->{bind_to} = "none";
my %hash;
$hash{value} = $hash_mpi{value};
#{$parallel_hash{"params_name_$i"}} = ("reporter","xml_obj",$hash{value});
is a weird way of doing
my $value = { bind_to => "none" };
$parallel_hash{ "params_name_$i" } = [ "reporter", "xml_obj", $value ];
You're adding a reference to same hash to every array.
You want
my %parallel_hash;
for my $i ( 0 .. 2 ) {
$parallel_hash{ "function_name_$i" } = "sharp_mpi_steps::run_mpirun";
my %hash = ( # Create a new hash.
bind_to => "none",
reporter_message => "process_$i",
);
$parallel_hash{ "params_name_$i" } = [
"reporter",
"xml_obj",
\%hash, # Create a reference to that hash.
];
}
{} does those two things at once.
my %parallel_hash;
for my $i ( 0 .. 2 ) {
$parallel_hash{ "function_name_$i" } = "sharp_mpi_steps::run_mpirun";
$parallel_hash{ "params_name_$i" } = [
"reporter",
"xml_obj",
{
bind_to => "none",
reporter_message => "process_$i",
}
];
}
That's a very weird data structure, by the way. Using an array would make more sense.
my #data;
for my $i ( 0 .. 2 ) {
push #data, {
function => "sharp_mpi_steps::run_mpirun",
params => [
"reporter",
"xml_obj",
{
bind_to => "none",
reporter_message => "process_$i",
}
],
};
}

Perl Issue trying to add static text by IP address

I have a script that has an exact count of IP address' being compared to an expected count of IP address going though a specific port.
Code:
my %minimum = (
'10.10.10.10' => 2,
'10.10.10.11' => 3,
'10.10.10.12' => 6,
'10.10.10.13' => 7,
);
my %count;
open my $fh, '-|', 'netstat -an |grep 1111 ' or die "could not run netstat: $!";
while(<$fh>) {
next unless /^\s*............(regex) /;
$count{$1}++;
}
close $fh;
while(my ($ip, $expected) = each %minimum) {
$count{$ip} ||= 0;
next if $count{$ip} == $expected && print color("green"), "$ip: OK! Expected = $expected count = $count{$ip}\n", color("reset");
print color("red"), "$ip: BAD! Expected = $expected count = $count{$ip}\n", color("reset");
}
I'm trying to add a static hostname. Currently an example output looks like:
10.10.10.10: OK! Expected = 2 Actual = 2
10.10.10.11: OK! Expected = 3 Actual = 3
10.10.10.12: OK! Expected = 6 Actual = 6
10.10.10.13: BAD! Expected = 7 Actual = 5
But I want to include a static hostname to look like below:
10.10.10.10: aaaa#aa.com OK! Expected = 2 Actual = 2
10.10.10.11: bbb#aa.com OK! Expected = 3 Actual = 3
10.10.10.12: ccc#aa.com OK! Expected = 6 Actual = 6
10.10.10.13: ddd#aa.com BAD! Expected = 7 Actual = 5
Thank you all for any recommendations/tips.
You could create a second hash to keep the info, keyed on the ip addresses, or you could create a nested data structure like so:
my %minimum = (
'10.10.10.10' => { label => 'hotdog', count => 2 },
'10.10.10.11' => { label => 'burger', count => 3 },
'10.10.10.12' => { label => 'steak', count => 6 },
'10.10.10.13' => { label => 'pizza', count => 7 },
);
and then later, when you need the info, you can retrieve it:
while(my ($ip, $data) = each %minimum) {
$count{$ip} ||= 0;
my $label = $data->{label};
my $expected = $data->{count};
# ... rest of code here ...
}
my %notes = (
'10.10.10.10' => 'cheeseburger',
'10.10.10.11' => 'hotdog',
'10.10.10.12' => '...',
'10.10.10.13' => '...',
);
s{^([^:]*):\K}{ defined($notes{$1}) ? " $notes{$1}" : "" }e;

How do I access a specific return value from the CDBI::Search function?

I am using a DB::CDBI class for accessing the database in our application. Our project is in object-oriented Perl.
package LT::LanguageImport;
use strict;
use warnings;
use base 'Misk5::CDBI';
__PACKAGE__->table( 'english_text_translation' );
__PACKAGE__->columns( Primary => qw/english language translation/ );
__PACKAGE__->columns( Essential => qw/english language translation/ );
__PACKAGE__->has_a( english => 'LT::EnglishLanguage' );
In one such scenario, I am supposed to check if a row in a table exists. I am using the built-in search API in a CDBI call.
sub find_translation {
my $translation_exists_r_not = $class->search(
english => $english,
language => $language,
translation => $translation
);
return;
}
$translation_exists_r_not is getting the expected values depending on the inputs given in the search. If the row exists, then the _data is updated with the row details.
$translation_exists_r_not = bless({
'_data' => [
{
'language' => 'polish',
'translation' => 'Admin',
'english' => 'admin'
}
],
'_place' => 0,
'_mapper' => [],
'_class' => 'LT::LanguageImport'
},
'Class::DBI::Iterator'
);
If the row desn't exist, then I get a return value like this.
$translation_exists_r_not = bless({
'_data' => [],
'_place' => 0,
'_mapper' => [],
'_class' => 'LT::LanguageImport'
},
'Class::DBI::Iterator'
);
I want to return the value of translation from this sub find_translation depending on the search result. I am not able to get a best condition for this.
I tried copying the _data into an array, but I'm not sure how to proceed further. As _data will be an empty arrayref and another condition it will have a hashref inside the arrayref.
my #Arr = $translation_exists_r_not->{'_data'};
CDBI's search method will return an iterator, because there may be multiple rows returned depending on your criteria.
If you know there can be only one row that matches your criteria, you want to use the retrieve method, i.e.:
if (my $translation_exists_r_not = $class->retrieve(
english => $english,
language => $language,
translation => $translation
)){
return [$translation_exists_r_not->translation,
'Misk5::TranslationAlreadyExists']
}
else {
return [ '', undef ]
}
And if multiple rows can be returned from your search, and you're only interested in the truthiness, then again, don't be rummaging around inside the CDBI::Iterator, but use its methods:
my $translation_exists_r_not = $class->search(
english => $english,
language => $language,
translation => $translation
); # returns an iterator
if ($translation_exists_r_not){
my $first = $translation_exists_r_not->first;
return [ $first->translation, 'Misk5::TranslationAlreadyExists' ]
}
Have a look at perldoc Class::DBI and perldoc Class::DBI::Iterator. CDBI has excellent documentation.
I think I got the solution. Thanks to whoever has tried to solve it.
my #req_array = %$translation_exists_r_not->{_data};
my $length_of_data = '9';
foreach my $elem (#req_array) {
$length_of_data = #{$elem};
}
Now check the length of the array.
if ($length_of_data == 0) {
$error = '';
$result = [undef, $error];
}
Now check if it is one.
if ($length_of_data == 1) {
my #result_array = #{%$translation_exists_r_not->{_data}};
my $translation = $result_array[0]{'translation'};
$error = 'Misk5::TranslationAlreadyExists';
$result = [$translation, $error];
}
return #$result;

how to query eXist using XPath?

I decided to use eXist as a database for an application that I am writing in Perl and
I am experimenting with it. The problem is that I have stored a .xml document with the following structure
<foo-bar00>
<perfdata datum="GigabitEthernet3_0_18">
<cli cmd="whatsup" detail="GigabitEthernet3/0/18" find="" given="">
<input_rate>3</input_rate>
<output_rate>3</output_rate>
</cli>
</perfdata>
<timeline>2011-5-23T11:15:33</timeline>
</foo-bar00>
and it is located in the "/db/LAB/foo-bar00/2011/5/23/11_15_33.xml" collection.
I can successfully query it, like
my $xquery = 'doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")' ;
or $xquery can be equal to
= doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")/foo-bar00/perfdata/cli/data(output_rate)
or
= doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")/foo-bar00/data(timeline)
my ($rc1, $set) = $eXist->executeQuery($xquery) ;
my ($rc2, $count) = $eXist->numberOfResults($set) ;
my ($rc3, #data) = $eXist->retrieveResults($set) ;
$eXist->releaseResultSet($set) ;
print Dumper(#data) ;
And the result is :
$VAR1 = {
'hitCount' => 1,
'foo-bar00' => {
'perfdata' => {
'cli' => {
'given' => '',
'detail' => 'GigabitEthernet3/0/18',
'input_rate' => '3',
'cmd' => 'whatsup',
'output_rate' => '3',
'find' => ''
},
'datum' => 'GigabitEthernet3_0_18'
},
'timeline' => '2011-5-23T11:15:33'
}
};
---> Given that I know the xml document that I want to retrieve info from.
---> Given that I want to retrieve the timeline information.
When I am writing :
my $db_xml_doc = "/db/LAB/foo-bar00/2011/5/23/11_15_33.xml" ;
my ($db_rc, $db_datum) = $eXist->queryXPath("/foo-bar00/timeline", $db_xml_doc, "") ;
print Dumper($db_datum) ;
The result is :
$VAR1 = {
'hash' => 1717362942,
'id' => 3,
'results' => [
{
'node_id' => '1.2',
'document' => '/db/LAB/foo-bar00/2011/5/23/11_15_33.xml'
}
]
};
The question is : How can I retrieve the "timeline" info ? Seems that the "node_id" variable (=1.2) can points to the "timeline" info, but how can I use it ?
Thank you.
use XML::LibXML qw( );
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file('a.xml');
my $root = $doc->documentElement();
my ($timeline) = $root->findnodes('timeline');
if ($timeline) {
print("Exists: ", $timeline->textContent(), "\n");
}
or
my ($timeline) = $root->findnodes('timeline/text()');
if ($timeline) {
print("Exists: ", $timeline->getValue(), "\n");
}
I could have used /foo-bar00/timeline instead of timeline, but I didn't see the need.
Don't know if you're still interested, but you could either retrieve the doc as DOM and apply an xquery to the DOM, or, probably better, only pull out the info you want in the query that you submit to the server.
Something like this:
for $p in doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")//output_rate
return
<vlaue>$p</value>