How to fix 'strpos(): Offset not contained in string' on this code - php

Some of my code is throwing error some times, and can't find why.
The error is strpos(): Offset not contained in string on the while statement.
I know what this error means, but I don't know why sometimes I have this error...
Here is the part of code:
if(!empty($args['name'])){
$p = 0;
while(($p = strpos($args['name'],'&',$p)) !== false){
if(substr($args['name'],$p,5) == '&'){
$p += 5;
}else{
++$p;
$args['name'] = substr($args['name'],0,$p).'amp;'.substr($args['name'],$p);
$p += 4;
}
}
}
I tried to change the While statement by:
while(strlen($args['name']) >= $p && ($p = strpos($args['name'],'&',$p)) !== false){
But it doesn't fix the issue.
By the way, this code comes from a wordpress plugin, here is the doc:
/** A workaround for seems to be an overlook in WordPress core.
* Dealing with '&' in term name.
* A term name containing '&' is stored in database with '&' instead of '&',
* but search in get_terms is done on raw '&' coming from $_POST variable.
*/
Do you have any ideas? Why this code is sometimes wrong?
Thank you
FIXED
My variable was an Array ...

This code should work fine. Is ok.
In your case $p can't be greater than your paramater.
Please just be sure that your parameter $args['name'] is a string. I'm pretty sure it's not.
I'd bet it's an array (is_array())

Please check the $args['name'] before your while loop
Add if(isset($args['name'])) or more sure with if(!empty($args['name']))

Related

PHP strange behaviour - variables appear unset unless print()ed

I am posting a form to a script with this code:
foreach($_POST as $k=>$v){
if(!is_array($v)){$$k=dbenc($v);} else{$$k=$v;}
$_SESSION["cat"][$k]=$v;
}
$url=vlookup("url","cat","cat=$cat");
// $cat is an integer which originated from the same field value and has been re-posted
"vlookup" is:
function vlookup($field,$table,$criteria){
global $link;
if($table<>""){$from="FROM $table";}
if($criteria<>""){$criteria="WHERE $criteria";}
$r=mysqli_query($link,"SELECT $field as v $from $criteria") or die("VLOOKUP FAILED: $field $from $criteria".mysqli_error($link));
$n=mysqli_num_rows($r);
if($n>0){
$row=mysqli_fetch_assoc($r) or die(mysqli_error($link));
return $row["v"];
}
}
The problem is that
print($cat);exit;
gives the expected result, but $cat does not appear in function output such as
showerror("$cat not found");
and the "vlookup" relying on it produces an error suggesting there is nothing after the =
Printing the query in the error report confirms the absence of the $cat value in the vlookup function.
This makes no sense!
Any thoughts or advice appreciated.
As per my comment above, the problem seems to be the use of false in
if (strpos($value," ")!==false && ...)
after the vlookup using $cat
If I test for spaces without using !==false in combination with other tests, dynamic variables appear as normal. Not sure if this is to be expected?

PHP eval not executing properly

Could someone point out what I'm mistaking here? :)
<?php
$q = $_GET[q];
$acuman = <<<PARSE
input: (contains: "hello"){
output: "hello";
}
PARSE;
$acuman = str_replace("input: (contains: ", 'if(strpos(', $acuman);
$acuman = str_replace("){", ', $q) !== false) {', $acuman);
$acuman = str_replace("output: ", '$output = ', $acuman);
eval($acuman);
?>
I'm attempting to execute the string $acuman, a heredoc which has been altered by various str_replace functions. However, it is not doing what I intend it to do, and I am confused as of what to do as I've tried many different things.
Since many people seemed confused: My intention is for the code in the string $acuman to be executed as code properly. I just want the eval function to work. I know that eval is evil, please, stop: I'm just asking for help for solving the problem at hand.
Edit: When I echo the string $acuman, this is what I get:
if(strpos("hello", $q) !== false) { $output = "hello"; }
You have the arguments in the wrong order:
if(strpos($q, "hello") !== false) { $output = "hello"; }
strpos() takes the "haystack" (string being searched) as the first argument and the "needle" (string to find as within the "haystack") as the second argument.
Ok, so... $acuman appears to contain the following:
if(strpos("hello", $q) !== false) {
echo "hello";
}
Which indicates that $q needs to contain a portion of "hello" to echo the string "hello".
I don't see any problem here, EXCEPT that $q = $_GET[q]; won't work with any modern version because q is treated like a constant, not a variable nor a string literal array index. See this PHP documentation on the subject.
Upon changing to $q = $_GET['q']; instead (note the quotes), it seems like this code actually works. It will output "hello" whenever passing any portion of "hello" to the URL parameter (which gets passed to the PHP code).
Needless to say: Do not use this code for production. The code as it is is very vulnerable and allows a user to pass raw PHP code through to your script to execute. The function of this code can be completely re-written in a much safer manner, but you have expressed the desire to continue using eval(); so please be careful.
Enjoy.

Cannot use string offset as an array (What does it mean?)

The code below is more or less a chunk of my code. The $servername and $monthlyincome variables are not actually static as shown here but I changed them so I could add less code here.
If I run this code...
$servername="Server1";
$months = array('January','February','March','April','May','June','July','August','September','October','November','December');
for ($i=0;$i<=24;$i++) {
$new_time = mktime(0,0,0,date("m")+$i,1,date("Y"));
$months_array[date("Y",$new_time)][date("m",$new_time)] = "x";
}
$overallincome = 0;
foreach ($months_array AS $year=>$month) {
foreach ($month AS $mon=>$x) {
$monthlyincome = 3;
$overallincome += $monthlyincome;
$$servername[$months[$mon-1]." ".$year]['monthlyincome']=$monthlyincome;
$$servername[$months[$mon-1]." ".$year]['overallincome']=$overallincome;
}
}
I get this error...
Cannot use string offset as an array in on line 123
Line 123 is this line... $$servername[$months[$mon-1]." ".$year]['monthlyincome']=$monthlyincome;
I can't figure out what I am doing wrong. I have checked other posts on SO with the same error but nothing made sense to me.
Putting it as an answer, then!
$$servername[] seems to be the problem. It's interpreting it as ${$servername[]} where you want it to interpret as ${$servername}[].
Try putting those curly-brackets in there and see if that helps.

Add/Replace URL GET parameter depending on current URL

I’ve tried for some time now to solve what probably is a small issue but I just can’t seem get my head around it. I’ve tried some different approaches, some found at SO but none has worked yet.
The problem consists of this:
I’ve a show-room page where I show some cloth. On each single item of cloth there is four “views”
Male
Female
Front
Back
Now, the users can filter this by either viewing the male or female model but they can also filter by viewing front or back of both gender.
I’ve created my script so it detects the URL query and display the correct data but my problem is to “build” the URL correctly.
When firstly enter the page, the four links is like this:
example.com?gender=male
example.com?gender=female
example.com?site=front
example.com?site=back
This work because it’s the “default” view (the default view is set to gender=male && site=front) in the model.
But if I choose to view ?gender=female the users should be able to filter it once more by adding &site=back so the complete URL would be: example.com?gender=female&site=back
And if I then press the link to see gender=male it should still keep the URL parameter &site=back.
What I’ve achived so far is to append the parameters to the existing URL but this result in URL strings like: example.com?gender=male&site=front&gender=female and so on…
I’ve tried but to use the parse_url function, the http_build_query($parms) method and to make my “own” function that checks for existing parameters but it does not work.
My latest try was this:
_setURL(‘http://example.com?gender=male’, ‘site’, ‘back’);
function _setURL($url, $key, $value) {
$separator = (parse_url($url, PHP_URL_QUERY) == NULL) ? '?' : '&';
$query = $key."=".$value;
$url .= $separator . $query;
var_dump($url); exit;
}
This function works unless the $_GET parameter already exists and thus should be replaced and not added.
I’m not sure if there is some “best practice” to solve this and as I said I’ve looked at a lot of answers on SO but none which was spot on my issue.
I hope I’ve explained myself otherwise please let me know and I’ll elaborate.
Any help or advice would be appreciated
You can generate the links dynamically using the following method:
$frontLink = (isset($_GET['gender'])) ? 'mydomain.com?gender='.$_GET['gender'].'&site=front':'mydomain.com?site=front';
$backLink = (isset($_GET['gender'])) ? 'mydomain.com?gender='.$_GET['gender'].'&site=back':'mydomain.com?site=back';
This is a 1 line if statement which will set the value of the variables $frontLink and $backlink respectively. The syntax for a 1 line if statement is $var = (if_statement) ? true_result:false_result; this will set the value of $var to the true_result or false_result depending on the return value of the if statement.
You can then do the same for the genders:
$maleLink = (isset($_GET['site'])) ? 'mydomain.com?gender=male&site='.$_GET['site']:'mydomain.com?gender=male';
$femaleLink = (isset($_GET['site'])) ? 'mydomain.com?gender=female&site='.$_GET['site']:'mydomain.com?gender=female';
Found this by searching for a better solution then mine and found this ugly one (That we see a lot on the web), so here is my solution :
function add_get_parameter($arg, $value)
{
$_GET[$arg] = $value;
return "?" . http_build_query($_GET);
}
<?php
function requestUriAddGetParams(array $params)
{
$parseRes=parse_url($_REQUEST['REQUEST_URI']);
$params=array_merge($_GET, $params);
return $parseRes['path'].'?'.http_build_query($params);
}
?>
if(isset($_GET['diagid']) && $_GET['diagid']!='') {
$repParam = "&diagid=".$_GET['diagid'];
$params = str_replace($repParam, "", $_SERVER['REQUEST_URI']);
$url = "http://".$_SERVER['HTTP_HOST'].$params."&diagid=".$ID;
}
else $url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']."&diagid=".$ID;

php activerecord save does not work in codeigniter

I use the latest code igniter (2.0.3) and php-active 0.0.1.
All are working fine except save();
Code:
if($_POST)
{
$entry= Customers::find_by_routeid('4');
$entry->routeid=5;
$entry->save();
}
Here's my problem: for some reason that I cannot understand the above code does not work, but if I take the code out of if ($_POST), it works fine.
What I am doing wrong?
EDIT:
Thanks Damien Pirsy $this->input->post() does the trick, but when I uncomment the comments in the code the problems returns.
The code now is:
if($this->input->post())
{
$id = $this->input->post('id');
$oldRoute = $this->input->post('oldRoute');
$newRoute = $this->input->post('newRoute');
$entry= Customers::find_by_routeid($this->input->post('oldRoute'));
$entry->routeid=$this->input->post('newRoute');
$entry->save();
/*
if($oldRoute<$newRoute)
{
for ($i=$newRoute; $i>$oldRoute; $i--)
{
$element = Customers::find_by_routeid($i);
echo $element->routeid -= 1;
$element->save();
}
}
*/
}
The elements new IDs ($element->routeid -= 1;) are echoing right, but I have the same problem as in the beginning and neither of two saves work.
You didn't provide much details or debug info, so I'll just guess: try using the CI's native post handler instead. You should have var_dump()ed the $_POST array, see if isset() or not, also, since you're using it as a condition
if($this->input->post())
{
//...
}
UPDATE:
Since we're talking about Post variables, don't assume they're exactly as you want them. Keep in mind that $this->input->post('field') returns FALSE when the index is not present; that might well brake your if condition.
Assuming you need numbers to do this, you can do a check like
if($this->input->post('newRoute') AND is_numeric($this->input->post('newRoute'))
{
$newRoute = $this->input->post('newRoute');
}
else
{
// give it a default value, or raise an error, for example. If you need this
// variables, and need them to be numbers, you cannot go on in case these
// conditions are not met, right?
}
And the same for $oldRoute.
And yeah, OK, maybe you can write a cleaner code than mine, but you get the picture ;)

Categories