PHP Serialized database entries messing me all up - php

O.K. so I'm pretty clever - I've made a library for keeping a bunch of WP themes that are all set up to my needs so when I put out a new site I can just create the new blog in a few minutes.
As a holder for the new domain everything in the sql file that has the old domain in it I replace with [token].
Everything was working fine right up to the point where I made one with a child theme that apparently serialized data before entering it into the database. End up with stuff like this:
Theme','a:8:{s:12:\"header_image\";s:92:\"http://[token]wp-content/uploads/2011/05/494-Caring-for-fruit-trees-PLR.jpg\";s:16:\"background_image
So I dig into serialization and it turnss out that s:92 bit for example is the number of characters in that value. Since i'm changing [token] it changes and breaks.
Up till now I did all my changes to the sql file and didn't edit the database other than to populate it with the sql file - but I'm at a loss on how to deal with the data in the serial array.
Any ideas?

Easiest way would be to grab that data and use the unserialize() function, like
$arr = unserialize($data);
Then edit the data that way. When you're done, re-serialize it with serialize(), and store it back. You may have to to do a print_r() on the unserialized data to see how it's stored to see what you need to edit.
If you do the changes directly from the serialized data, you'll have to get the length of the current substring, make the change, then get the new length and splice that back into the serialized data, which is way more complicated than it needs to be.

Related

Value dissapears on live site after editing DB value

I have an issue with a Wordpress premium theme and MySQL database. The value in the database box looks like this:
a:1{i:0;a:4{s:4:"name";s:9:"Trailer";s:6:"select";s:6:"iframe";s:6:"idioma";s:2:"en";s:3:"url";s:82:"https://youtube.com/sample.mp4
";}}
When I edit the YouTube link value to something else, the entire data in this box disappears on the live Wordpress page, although it is visible in the database even after refresh. I have no idea why this happens and how I can keep it from happening.
EDIT:
After i tried editing other values like post_title etc it just wont update the values at all on the live WP page.Why im doing this is because i need to add and edit mass amounts of data easily with scripts.
The string you are displaying is coming from PHP serialize. This is a way for PHP to stringify any value for later usage.
If you want to mass modify those values, your best bet is to create a PHP script that fetch the data, unserializes it, make change directly to the PHP variable it created, and serialize again to put to database.
If you want to play with the string directly, you will need to make sure you are careful.
The main reason why changing the URL of the youtube video doesn't work is because you might not be changing the string declaration too.
s:82:"https://youtube.com/sample.mp4";
This is invalid. It is split into 3 parts, using :. Type:Length:Value. So it is a string of length 82, yet you provide a 30 character string.
If you turn on NOTICE in PHP you will certainly see the errors about it.
EDIT:
After tinkering a bit on PHPFiddle.org I came up with a clean string from the one you gave, which has numerous flaws...
a:1:{i:0;a:4:{s:4:"name";s:7:"Trailer";s:6:"select";s:6:"iframe";s:6:"idioma";s:2:"en";s:3:"url";s:30:"https://youtube.com/sample.mp4";}}
Note that I changed the Length values in 2 parts, and added 2 semi-colon :

How to parse CSV file in PHP and store fields in a database?

I need help parsing the following a CSV file in PHP, so I can insert the contents into a database.
I know I use file_get_contents() but after that I feel a bit lost.
What I'd like to store.
Collection1 - events.text & date
Collection2 - position & name.text & total
I'm not sure how best structure the data to insert into a database table.
"**collection1**"
"events.href","**events.text**","**date**","index","url"
"tur.com/events/classic.html","John Deere Classic","Thursday Jul 9
- Sunday Jul 12, 2015","1","tur.com/r.html"
"collection2"
"**position**","name.href","**name.text**","**total**","index","url"
"--","javascript:void(0);","Scott","--","2","tur.com/r.html"
"--","javascript:void(0);","Billy","--","3","tur.com/r.html"
"--","javascript:void(0);","Jon","--","4","tur.com/r.html"
"--","javascript:void(0);","Bill","--","5","tur.com/r.html"
"--","javascript:void(0);","Tim","--","6","tur.com/r.html"
"--","javascript:void(0);","Carlos","--","7","tur.com/r.html"
"--","javascript:void(0);","Robert","--","8","tur.com/r.html"
"--","javascript:void(0);","Rod","--","9","tur.com/r.html"
As per your previous question, I think this needs to be broken down into sections. As it stands it is rather too broad to answer.
Read the information using file_get_contents(). Make sure this works first, by echoing it to the console. (It sounded from your other question that you felt this would not work if the URL does not have a .csv suffix. It should work regardless of the file extension - try it. If it fails it may be dependent on cookies or JavaScript or some other problem).
Design and create your table structure in MySQL. It seems like you have two tables. They should both have a primary key. Are they related in some fashion? If so, perhaps one has a foreign key to the other one?
Explode your text file on the new line character and loop across the resulting array of lines.
If your CSV data has a title row in the first row position, delete that from your array.
For each line, read the elements of interest using PHP's build-in CSV parsing functions, and store them in variables.
Pass these variables to a custom function that saves the data.
For each save, you'll need to do an INSERT. I recommend using PDO here. Make sure you bind your parameters.
Where you get stuck on a specific problem, you can ask a new and focussed question. At present, the task is to break things down into discrete and researchable pieces.
One trick worth remembering is this shortcut to the PHP manual. If you do not know how fgetcsv works, for example, type php.net/fgetcsv into your browser address bar, and the PHP site will find the function for you. The documentation is excellent.

php array vs database for static data

I have an associative array in php consisting of about 4k elements.
Product Id and Product Name
a sample row:
'434353', 'TeaCups'
So no big data. In fact the whole php array file is about 80kb.
This is static data, so I won't be changing, deleting any data.
Considering the size of the array and the number of elements in it,
Would it be better to access data from the array or I should create
a database instead?
The data might be read about 20k times a day.
PS: Each time the data will be read, I will be fetching exactly one
element
If this is static data, I recommend you store this data in a JSON format as a file, that you can access via PHP using the fopen() function.
However, if the data becomes bigger, like lets say, 2 GB, or even 200 MB, unless if you have a supercomputer, you should use the database and query from there.
Note that databases are usually only useful when you have a lot of information, or if you have too much information to process in a regular JSON.

Extracting specific data from a large amount of data in a single "cell" of a mysql database

Long time reader first time questioner...
I'm attempting to use Drupal to create a set of variables, not the issue, it's all in place to set them and simple for the future operator to edit.
I then need to grab these values in php, still on the site but outside of Drupal to some extent. Again, although I'm a bit of a lightweight on PHP, I can get what I need. However drupal stores the data all in one "cell" (apologies, I've searched for what I'm after but I think my vocabulary is lacking to get the right result!). Here's an example of how it is stored:
a:3:{i:0;a:3:{s:5:"value";s:2:"38";s:5:"label";s:11:"Cost Per
M2";s:6:"weight";s:1:"0";}i:1;a:3:{s:5:"value";s:1:"7";s:5:"label";s:13:"Arch
Top
Cost";s:6:"weight";s:1:"1";}i:2;a:3:{s:5:"value";s:1:"5";s:5:"label";s:13:"Flat
Top Cost";s:6:"weight";s:1:"2";}}
So I can happily return the whole contents as above, but I haven't the slightest how to refine it down to a specific reference. I can work out the data is contained between certain sets of brackets so, one ref is:
{s:5:"value";s:2:"38";s:5:"label";s:11:"Cost Per M2";s:6:"weight";s:1:"0";}
What I really need is the "38" in the example, as this is a cost that a 2nd system uses a number of to calculate a final cost.
I hope this makes sense?
The value is serialised (see http://php.net/manual/en/function.serialize.php). What you want to do is unserialize it (see http://www.php.net/manual/en/function.unserialize.php). So it would be:
$deserializedValues = unserialize($values).
After that you can call the variables by doing:
$deserializedValues['value'] (if an array)
$deserializedValues->value (if an object)
Drupal returns JSON. The cleanest way to handle this would be to use PHP's json_decode() function:
http://php.net/manual/en/function.json-decode.php

Storing an array in a MySQL table

I have a 5 level multidimensional array. The number of keys in the array fluctuates but I need to store it in a database so I can access it with PHP later on. Are there any easy ways to do this?
My idea was to convert the array into a single string using several different delimiters like #* and %* and then using a series of explode() to convert the data back into an array when I need it.
I haven't written any code at this point because I'm hoping there will be a better way to do this. But I do have a potential solution which I tried to outline below:
here's an overview of my array:
n=button number
i=item number
btn[n][0] = button name
btn[n][1] = button desc
btn[n][2] = success or not (Y or N)
btn[n][3] = array containing item info
btn[n][3][i][0] = item intput type (Default/Preset/UserTxt/UserDD)
btn[n][3][i][1] = array containing item value - if more than one index then display as drop down
Here's a run-down of the delimiters I was going to use:
#*Button Title //button title
&*val1=*usr1234 //items and values
&*val2=*FROM_USER(_TEXT_$*name:) //if an items value contains "FROM_USER" then extract the data between the perenthesis
&*val3=*FROM_USER(_TEXT_$*Time:) //if the datatype contains _TEXT_ then explode AGAIN by $* and just display a textfield with the title
&*val4=*FROM_USER($*name1#*value1$*name2#*value2) //else explode AGAIN by $* for a list of name value pairs which represent a drop box - name2#*value2
//sample string - a single button
#*Button Title%*val1=*usr1234&*val2=*FROM_USER(_TEXT_$*name:)&*val3=*FROM_USER(_TEXT_$*date:)&*val4=*FROM_USER($*name1#*value1$*name2#*value2)
In summary, I am seeking some ideas of how to store a multidimensional array in a single database table.
What you want is a data serialization method. Don't invent your own, there are plenty already out there. The most obvious candidates are JSON (json_encode) or the PHP specific serialize. XML is also an option, especially if your database may support it natively to some degree.
Have a look at serialize or json_encode
The best decision for you is json_encode.
It has some advantages for json_encode beside serialize for storing in db.
taking smaller size
if you
must modify data manually in db there will be some problems with serialize, because this format stores size of values that has been serialized and modifying this values you must count and modify this params.
SQL (whether mySQL or any other variant) does not support array data types.
The way you are supposed to deal with this kind of data in SQL is to store it across multiple tables.
So in this example, you'd have one table that contains buttonID, buttonName, buttonSuccess, etc fields, and another table that contains buttonInputType and buttonInputValue fields, as well as buttonID to link back to the parent table.
That would be the recommended "relational" way of doing things. The point of doing it this way is that it makes it easier to query the data back out of the DB when the time comes.
There are other options though.
One option would be to use mySQL's enum feature. Since you've got a fixed set of values available for the input type, you could use an enum field for it, which could save you from needing to have an extra table for that.
Another option, of course, is what everyone else has suggested, and simply serialise the data using json_encode() or similar, and store it all in a big text field.
If the data is going to be used as a simple block of data, without any need to ever run a query to examine parts of it, then this can sometimes be the simplest solution. It's not something a database expert would want to see, but from a pragmatic angle, if it does the job then feel free to use it.
However, it's important to be aware of the limitations. By using a serialised solution, you're basically saying "this data doesn't need to be managed in any way at all, so I can't be bothered to do proper database design for it.". And that's fine, as long as you don't need to manage it or search for values within it. If you do, you need to think harder about your DB design, and be wary of taking the 'easy' option.

Categories