Undefined offset Error with array of exploded strings - php

I'm having some trouble with what is probably a very simple problem, but I just can't get my head around what the issue is.
I used fopen() to load a csv file, and broke it down into its different rows, loading the strings into an array of strings. I am trying to break apart each string to plug the values into a sql database.
$datalength is the number of lines there are in my csv file. The first line are the headings of the columns, so $x begins at 1.
for ($x=1;$x<$datalength;$x++)
{
$broken = explode(",",$lines[$x]);
$field1 = $broken[0];
$field2 = $broken[1];
$field3 = $broken[2];
$field4 = $broken[3];
echo $division;
$importdata = "INSERT INTO Teams (Field1,Field2,Field3,Field4)
Values ($field1,$field2,$field3,$field4)";
}
I keep getting the following error (BTW, I'm using WAMP):
Notice: Undefined offset: 1 in C:\wamp\www\test 2 (html-index)\upload_file.php on line 45, 46, 47
Lines 45-47 coincide with the $field2, $field3, and $field4 allocations of $broken[1] through $broken[3]. I don't understand why that is.
Anything I'm missing right off the bat? Any suggestions you think might make my life much easier would be warmly appreciated.

Anything I'm missing right off the bat?
Yes.
Something quite essential.
You are a virtual programmer. Your program deals not with the real data but with imaginary one. You imagine that some string you have can be exploded and put into array. While it is not. But, for some reason, you remain in a virtual world of your imagination and make no attempt to get in touch with a real one.
You are assuming that $lines[$x] contains a comma delimited string. Did you verify it?
You are assuming that $broken contains an array of four elements. Did you verify it?
Just by printing them out. This is so easy yet it will bring you into the real world at once - you will see the real data you process, not imaginary one. And be able to take any appropriate measures.
var_dump() is a best programmer's friend. Please make friends with this indispensable function too.
var_dump($lines[$x],$broken);
will clearly tell you, what's wrong with your offsets.

Related

php variable in an array

$q2=$_REQUEST['binge'];
'book2'=>array('callno'=>123006,'price'=>number_format(844,2),'desc'=>'Binge','auth'=>'Tyler Oakley','quant'=>$q2,'total'=>number_format(844,2)*$q2)
On this particular code, It kept displaying errors like this
Warning: A non-numeric value encountered in C:\xampp\htdocs\Webcard_3new\Webcard\wishlist.php on line 97
I searched all over the net for finding the right answers but some are just so complex to understand...
It supposed to be that $q2 is the variable inside an array. That variable is then multiplied to the "TOTAL". but the errors kept on going.. please help!!
The super-globals will always be strings. You need to explicitly convert them using intval():
$q2 = intval($_REQUEST['binge']);
Also, this line:
'book2'=>array...
Should be
$book2 = array...
You can use
$q2 = filter_var($_REQUEST['binge'], FILTER_VALIDATE_INT);
here you will have the benefit of validation where false is returned when someone passes a value that is not an integer. If it is instead a float use FILTER_VALIDATE_FLOAT instead.
Also, consider using $_GET, or $_POST directly to have more control of the data channel. $_REQUEST cobbles together several things into one, which sometimes may cause issues when more than one channel have the same key.

What's the most efficient way to grab data from this particular file?

I'm trying to think of the most efficient way to parse a file that stores names, studentids and Facebook ids. I'm trying to get the fbid value, so for this particular line it would be: 1281766051. I thought about using regex for this, but I'm a bit lost as to where to start. I thought about adding all this data to an array and chopping away at it, but it just seems inefficient.
{"name":"John Smith","studentid":"10358595","fbid":"1284556651"}
I apologise if the post is too brief. I'll do my best to add anything that I might have missed out. Thanks.
Well, this seems to be JSON, so the right way would be
$json = json_decode($str);
$id = $json->fbid;
The regex solution would look like this:
preg_match('/"fbid":"(\d+)"/', $str, $matches);
$id = $matches[1];
But I cannot tell you off the top of my head which of these is more efficient. You would have to profile it.
UPDATE:
I performed a very basic check on execution times (nothing too reliable, I just measured 1,000,000 executions of both codes). For your particular input, the difference is rather negligible:
json_decode: 27s
preg_match: 24s
However, if your JSON records get larger (for example, if I add 3 fields to the beginning of the string (so that both solutions are affected)), the difference becomes quite noticeable:
json_decode: 46s
preg_match: 30s
Now, if I add the three fields to the end of the string, the difference becomes even larger (obviously, because preg_match does not care about anything after the match):
json_decode: 45s
preg_match: 24s
Even so, before you apply optimizations like this, perform proper profiling of your application and make sure that this is actually a crucial bottleneck. If it is not, it's not worth obscuring your JSON-parsing code with regex functions.
That's JSON, use:
$str = '{"name":"John Smith","studentid":"10358595","fbid":"1284556651"}';
$data = json_decode($str);
echo $data->fbid;
Cheers
Use json_decode
$txt='{"name":"John Smith","studentid":"10358595","fbid":"1284556651"}';
$student =json_decode($txt);
echo $student->fbid;

splitting a string every 4 characters and then put those into new variables?

How would i split a string every 4 characters and then have every 4 characters put into a separate variable so i can do other stuff with each individual 4 characters?
Well, I don't really see you putting each of them in a different variable, because then you'll have like 10 variables:
$var1 = ...;
$var2 = ...;
$var3 = ...;
But you could use the str_split function as following:
$variable = str_split($origionalvar, 4);
it will create an array, which you can access:
$variable[0] to $variable[sizeof(variable)]
If you don't know about arrays, you really should read up on those. They are really great if you want to store a lot of similar information in an object and you don't want to create a new variable for it every time. Also you can loop over them very easily and do some other great stuff with them.
I assume you probably googled this question a bit too. You must have come across http://php.net/manual/en/function.str-split.php. Did you see this page, and if you did, did you have some trouble with it. If so perhaps we can help you reading the documentation properly.
Have a look at the str_split function. The PHP manual will tell you all you need to know.

PHP Change Array Over and Over

I have any array
$num_list = array(42=>'0',44=>'0',46=>'0',48=>'0',50=>'0',52=>'0',54=>'0',56=>'0',58=>'0',60=>'0');
and I want to change specific values as I go through a loop
while(list($pq, $oin) = mysql_fetch_row($result2)) {
$num_list[$oin] = $pq;
}
So I want to change like 58 to 403 rather then 0.
However I always end up getting just the last change and non of the earlier ones. So it always ends up being something like
0,0,0,0,0,0,0,0,0,403
rather then
14,19,0,24,603,249,0,0,0,403
How can I do this so it doesn't overwrite it?
Thanks
Well, you explicititly coded that each entry should be replaced with the values from the database (even with "0").
You could replace the values on non-zero-values only:
while(list($pq, $oin) = mysql_fetch_row($result2)) {
if ($pq !== "0") $num_list[$oin] = $pq;
}
I don't get you more clear, i thought your asking this only. Check this
while(list($pq, $oin) = mysql_fetch_row($result2)) {
if($oin==58) {
$num_list[$oin] = $pq;
}
}
In my simulated tests (although You are very scarce with information), Your code works well and produces the result that You want. Check the second query parameter, that You put into array - namely $pg, thats what You should get there 0,0,0,0,0...403 OR Other thing might be that Your $oin numbers are not present in $num_list keys.
I tested Your code with mysqli driver though, but resource extraction fetch_row is the same.
Bear in mind one more thing - if Your query record number is bigger than $numlist array, and $oin numbers are not unique, Your $numlist may be easily overwritten by the folowing data, also $numlist may get a lot more additional unwanted elements.
Always try to provide the wider context of Your problem, there could be many ways to solve that and help would arrive sooner.

Most efficient way to get data from the database to session

What is the quickest way to get a large amount of data (think golf) and the most efficient (think performance) to get a large amount of data from a MySQL database to a session without having to continue doing what I already have:
$sql = "SELECT * FROM users WHERE username='" . mysql_escape_string($_POST['username']) . "' AND password='" . mysql_escape_string(md5($_POST['password'])) . "'";
$result = mysql_query($sql, $link) or die("There was an error while trying to get your information.\n<!--\n" . mysql_error($link) . "\n-->");
if(mysql_num_rows($result) < 1)
{
$_SESSION['username'] = $_POST['username'];
redirect('index.php?p=signup');
}
$_SESSION['id'] = mysql_result($result, '0', 'id');
$_SESSION['fName'] = mysql_result($result, '0', 'fName');
$_SESSION['lName'] = mysql_result($result, '0', 'lName');
...
And before anyone asks yes I do really need to 'SELECT
Edit: Yes, I am sanitizing the data, so that there can be no SQL injection, that is further up in the code.
I came up with this and it appears to work.
while($row = mysql_fetch_assoc($result))
{
$_SESSION = array_merge_recursive($_SESSION, $row);
}
Most efficient:
$get = mysql_query("SELECT * FROM table_name WHERE field_name=$something") or die(mysql_error());
$_SESSION['data'] = mysql_fetch_assoc($get);
Done.
This is now stored in an array. So say a field is username you just do:
echo $_SESSION['data']['username'];
Data is the name of the array - username is the array field.. which holds the value for that field.
EDIT: fixed some syntax mistakes :P but you get the idea.
OK, this doesn't answer your question, but doesn't your current code leave you open to SQL Injection?
I could be wrong, never worked in PHP, just saw the use of strings in the SQL and alarm bells started ringing!
Edit:
I am not trying to tamper with your post, I was correcting a spelling error, please do not roll back.
I am not sure what you mean by "large amounts of data", but it looks to me like you are only initializing data for one user? If so, I don't see any reason to optimize this unless you have hundreds of columns in your database with several megabytes of data in them.
Or, to put it differently, why do you need to optimize this? Are you having performance problems?
What you are doing now is the straight-forward approach, and I can't really see any reason to do it differently unless you have some specific problems with it.
Wrapping the user data in a user object might help some on the program structure though. Validating your input is probably also a good idea.
#Unkwntech
Looks like you are correct, but following a Google, which led here looks like you may want to change to mysql_real_escape_string()
As for the edit, I corrected the spelling of efficient as well as removed the "what is the".. Since that's not really required since the topic says it all.
You can review the edit history (which nicely highlights the actual changes) by clicking the "edited a min ago" text at the bottom of your question.
Try using json for example:
$_SESSION['data'] = json_encode(mysql_fetch_array($result));
Is the implementation of that function faster than what he is already doing?
Does anyone else have trouble entering ] into markdown? I have to paste it in
Yes, it's bugged.
#Anders - there are something like 50-75 columns.
Again, unless this is actually causing performance problems in your application I would not bother with optimizing it. If, however, performance is a problem I would consider only getting some of the data initially and lazy-loading the other columns as they are needed.
If Unkwntech's suggestion does indeed work, I suggest you change your SELECT statement so that it doesn't grab everything, since your password column would be one of those fields.
As for whether or not you need to keep this stuff in the session, I say why not? If you're going to check the DB when the user logs in (I'm assuming this would be done then, no?) anyway, you might as well store fairly non-sensitive information (like name) in the session if you plan on using that information throughout the person's visit.
It's not so much that it causing performance problems but that I would like the code to look a bit cleaner.
Then wrap the user data in a class. Modifyng $_SESSION directly looks somewhat dirty. If you want to keep the data in a dictionary—which you can still do even if you put it in a separate class.
You could also implement a loop that iterates over all columns, gets their names and copy the data to a map with the same key names. That way your internal variables—named by key in the dictionary—and database column names would always be the same. (This also has the downside of changing the variable name when you change the column name in the database, but this is a quite common and well-accepted trade-off.)
Try using json for example:
$_SESSION['data'] = json_encode(mysql_fetch_array($result));
Edit
Later you then json_decode the $_SESSION['data'] variable and you got an array with all the data you need.
Clarification:
You can use json_encode and json_decode if you want to reduce the number of lines of code you write. In the example in the question, a line of code was needed to copy each column in the database to the SESSION array. Instead of doing it with 50-75 lines of code, you could do it with 1 by json_encoding the entire database record into a string. This string can be stored in the SESSION variable. Later, when the user visits another page, the SESSION variable is there with the entire JSON string. If you then want to know the first name, you can use the following code:
$fname = json_decode($_SESSION['data'])['fname'];
This method won't be faster than a line by line copy, but it will save coding and it will be more resistant to changes in your database or code.
BTW
Does anyone else have trouble entering ] into markdown? I have to paste it in.

Categories