News:

Bored?  Looking to kill some time?  Want to chat with other SMF users?  Join us in IRC chat or Discord

Main Menu

implode Array problem

Started by The Wizard, August 21, 2012, 03:41:42 PM

Previous topic - Next topic

The Wizard

objective - Start or add more data into a Column using - comma-delimited text

I'm using SMF 2.0.2

Assume there is a column in the SMF Database under each members profile called - wizard

example of data to be stored - image1, image2, image4, image20

What ever code is use must be in - function onUse()

My plan is to add - wizard - to the following code in Load.php

if ($set == 'normal')
{
$select_columns = '
IFNULL(lo.log_time, 0) AS is_online, IFNULL(a.id_attach, 0) AS id_attach, a.filename, a.attachment_type, wizard,

         
and add wizard here as well -

elseif ($set == 'profile')
{
$select_columns = '
     IFNULL(lo.log_time, 0) AS is_online, IFNULL(a.id_attach, 0) AS id_attach, a.filename, a.attachment_type, wizard,


I'm not sure if I need to add wizard to both places as I'm unsure as to how that code works so if you can answer this please do so.
I'm guessing in reads the info in the database and makes it available to use quickly. So thats how I plan on reading from the database
column - wizard

So this is what I'm thinking might work -

function onUse()

{

global $user_info;

// Get all previous items in  wizard and convert string to array

$W => explode (',', $profile['wizard']);

$Z => implode(',', $W, image12);

updateMemberData($user_info['id'], array('wizard' => '$Z'));

return '<br>You now own 12 long-stem roses.<br /><br />We here at Acme Florists division hopes that they will brighten your day.<br />
<br />Enjoy<br />
<br />Acme Division Products Company<br /><br />';
}


OK so what did I leave out and what did I do wrong?

Note: I'm working on - I guess you would call it a plug in for the SMF Shop mod so all the image files as stored where the shop mod is.
I know this is not good form, but I did not design the SMF Shop mod nor did I decide to put it in the Sources Dir.
I'm just trying to keep all the shop/plug in stuff together. Maybe some day I'll know enough to rework the SMF Shop mod until then lay off.
If you still want to point out this flaw take it up with the guys who reworked the mod to work with 2.0.2.   

         



The Wizard


emanuele

PHP's manual is your friend: http://php.net/manual/en/function.implode.php
implode accepts two arguments and only two.

So you should add it *before* imploding the array, e.g.
$W = explode (',', $profile['wizard']);
$W[] = 'image12';
$Z = implode(',', $W);

But then, I wonder why do you explode to just implode it again?
Better do something like:
$profile['wizard'] .= !empty($profile['wizard']) ? ',' : '' . 'image12';

Other random "mistakes":
1) when you assign a value to a variable you do it with an equal sign (=), not equal+greater than (=>),
2) equal+greater than (=>) is used when you assign values to array indexes:
array('index' => 'value');
3) strings should always be delimited by quotes (single or double, the two behave differently).


Take a peek at what I'm doing! ;D




Hai bisogno di supporto in Italiano?

Aiutateci ad aiutarvi: spiegate bene il vostro problema: no, "non funziona" non è una spiegazione!!
1) Cosa fai,
2) cosa ti aspetti,
3) cosa ottieni.

MrPhil

Quote from: emanuele on August 22, 2012, 09:54:37 AM
$profile['wizard'] .= !empty($profile['wizard']) ? ',' : '' . 'image12';
should probably be
$profile['wizard'] .= (!empty($profile['wizard']) ? ',' : '') . 'image12';
so that 'image12' is added on to the end regardless of whether a comma or null string is first added (operator precedence).

This all assumes that $profile['wizard'] is always defined in the first place. If there are cases where it might not be, you would want to check isset($profile['wizard']) and (if not) decide whether you want to create the array first, or just skip the whole operation.

The Wizard

For some reason all this does is rewrite over anything that's in the column - wizard.
If I have image1,image2,image4 in the column after using the code I get - image12

Do I need to use a global to call up stuff on the Load.php? if so what do I use? - just my guess.

Wiz

function onUse()
{
global $user_info;

$profile['wizard'] .= (!empty($profile['wizard']) ? ',' : '') . 'image12';

updateMemberData($user_info['id'], array('wizard' => $profile['wizard']));

return '<br>You now own 12 long-stem roses.<br /><br />We here at Acme Florists division hopes that they will brighten your day.<br />
<br />Enjoy<br />
<br />Acme Division Products Company<br /><br />';
}

emanuele

Then something less compact:
$profile['wizard'] = $profile['wizard'] . (!empty($profile['wizard']) ? ',' : '') . 'image12';


Take a peek at what I'm doing! ;D




Hai bisogno di supporto in Italiano?

Aiutateci ad aiutarvi: spiegate bene il vostro problema: no, "non funziona" non è una spiegazione!!
1) Cosa fai,
2) cosa ti aspetti,
3) cosa ottieni.

The Wizard

Sorry I still get the same problemit just wrights over all the data in the column.

Here is the latest code -
function onUse()
{

global $user_info;

    $profile['wizard'] = $profile['wizard'] . (!empty($profile['wizard']) ? ',' : '') . 'image12';

updateMemberData($user_info['id'], array('wizard' => $profile['wizard']));

return '<br>You now own 12 long-stem roses.<br /><br />We here at Acme Florists division hopes that they will brighten your day.<br />
<br />Enjoy<br />
<br />Acme Division Products Company<br /><br />';
}

The Wizard

Ok form the limited test I have been able to run it looks like the code is not reading
Quote$profile['wizard']
.

emanuele

Well, that was another bug I overlooked whan I wrote all the others... :P

Of course you have to use the variable you have available, not one that you used in another function.
So it will *probably* (no idea because I don't remember all the code) $user_info['wizard']


Take a peek at what I'm doing! ;D




Hai bisogno di supporto in Italiano?

Aiutateci ad aiutarvi: spiegate bene il vostro problema: no, "non funziona" non è una spiegazione!!
1) Cosa fai,
2) cosa ti aspetti,
3) cosa ottieni.

The Wizard

You mean something like this. By the way the code below does not work. All it does is rewrite over the data in the column.

function onUse()
{

global $profile, $user_info;


$profile['wizard'] = $profile['wizard'] . (!empty($profile['wizard']) ? ',' : '') . 'image12';

    updateMemberData($user_info['id'], array('wizard' => $profile['wizard']));

return '<br>You now own 12 long-stem roses.<br /><br />We here at Acme Florists division hopes that they will brighten your day.<br />
<br />Enjoy<br />
<br />Acme Division Products Company<br /><br />';
}

The Wizard

function onUse()
{

global $profile;

$array = explode (',', $profile['wizard']);
echo $array;
$array[] = 'image12';
$array = implode(',', $array);
echo $array;

}

   
I broke this down to make it simple for me to understand.
I get the following results - Array,image12

I want to get - image1,image2,image3,image12

So why am I getting the word Array and not image1,image2,image3 ?

MrPhil

What was $profile['wizard'] before you exploded it into $array? What does $array look like after the explode()? Does it have three elements 'image1', 'image2', and 'image3'? How about after appending element 'image12'? I suspect that $profile['wizard'] is not what you think it is -- possibly empty or even unset.

The Wizard

Hello:

I have been using phpMyadmin to insert the test data as I know that the column - wizard has the following data in it - image1,image2,image3

I'm trying to read from a single members wizard column and then add data in this case the test data is - image12. I'm still trying to understand arrays and how SMF works.


MrPhil

Did you actually print out $profile['wizard'] at the beginning of this code segment? It's possibly not getting to your code like you think it is?

emanuele

$profile is a variable available only in the function loadMemberContext, you cannot use it anywhere else (to put it easy).
$user_profile is a variable that can be used (almost) anywhere in SMF's codebase.

That said, my previous comment:
Quote from: emanuele on August 22, 2012, 12:45:06 PM
Of course you have to use the variable you have available, not one that you used in another function.
So it will *probably* (no idea because I don't remember all the code) $user_info['wizard']
means that if you are in a function that is not loadMemberContext you cannot use $profile, and most likely you will have to use $user_info (i.e. replace all instances of $profile with $user_info).


Take a peek at what I'm doing! ;D




Hai bisogno di supporto in Italiano?

Aiutateci ad aiutarvi: spiegate bene il vostro problema: no, "non funziona" non è una spiegazione!!
1) Cosa fai,
2) cosa ti aspetti,
3) cosa ottieni.

The Wizard

Hello:

Since I'm getting nowhere with the approach above I decide to try another approach below -

function onUse()
{
global $db_prefix, $modSettings, $txt;
global $smcFunc, $context, $txt, $scripturl;
global $user_info;
     global $settings, $options;


// Get the user's information
$result = $smcFunc['db_query']('', "
SELECT wizard
FROM {db_prefix}members

LIMIT 1",
array(
'wizard' => $wizard,
));

    // Get their information
$row = $smcFunc['db_fetch_assoc']($result);

// if you use print_r($row); you get - Array ( [wizard] => image1,image2,image3 )
print_r($row);

// Turn Array into String
    // if you use $row you get - Piece 0 = i

        $wordChunks = implode(',', $row);
for($i = 0; $i < count($wordChunks); $i++){
        echo "Piece $i = $wordChunks[$i] <br />";
            }



}


As you can see from my notes -  if I use print_r($row); I get  - Array ( [wizard] => image1,image2,image3 )

So I think I'm on the right path, but feel free to tell me if I'm not. I just can't figure out how to convert the array into a string?

Note: My goal at the beginning of this thread is still where I want to get too, but I want to understand how to do it and for me breaking it down into small parts is the way to go.

Wiz



emanuele

FROM {db_prefix}members

LIMIT 1

You missed the "WHERE" clause. What does it mean? That this query will always return the "wizard" value of the "first" member.

This is wrong:
array(
'wizard' => $wizard,
));


See the wiki for documentation: http://wiki.simplemachines.org/smf/Db_query (still need a bit of improvement on that respect though).
And http://wiki.simplemachines.org/smf/$smcFunc for the other functions.

In short in the "array" you should put values that will be used "into" the query, a possible correct query is:

// Get the user's information
$result = $smcFunc['db_query']('', "
SELECT wizard
FROM {db_prefix}members
WHERE id_member = {int:current_member}
LIMIT 1",
array(
'current_member' => $user_info['id'],
));

You see that "current_member" is present both in the array and in the query itself, that because the value $user_info['id'] will be put where there is "{int:current_member}".
Longer explanation: it's "good" to do like that because the function $smcFunc['db_query'] will take care of sanitize the values passed through the array, for example in that case the value $user_info['id'] will be casted to int (equivalent of (int) $user_info['id']) and then used into the query. This is done automatically to avoid SQL-injections.

Unfortunately this query could return wrong results depending on where you use it, but since your goal is still to modify loadMember and loadMemberContext is fine.


        $wordChunks = implode(',', $row);

implode convert an array to a string, what you should do here is convert a string into an array, so you should use explode. ;)


Take a peek at what I'm doing! ;D




Hai bisogno di supporto in Italiano?

Aiutateci ad aiutarvi: spiegate bene il vostro problema: no, "non funziona" non è una spiegazione!!
1) Cosa fai,
2) cosa ti aspetti,
3) cosa ottieni.

The Wizard

Hello emanuele and thanks again for all the support adn help.

I'm sorry to say that the code does not work. Below is a copy of the code I was using -
function onUse()
{
global $db_prefix, $modSettings, $txt;
global $smcFunc, $context, $txt, $scripturl;
global $user_info;
     global $settings, $options;


// Get the user's information
    // Get the user's information
$result = $smcFunc['db_query']('', "
SELECT wizard
FROM {db_prefix}members
WHERE id_member = {int:current_member}
LIMIT 1",
array(
'current_member' => $user_info['id'],
));


    // Get their information
$row = $smcFunc['db_fetch_assoc']($result);

// if you use print_r($row); you get - Array ( [wizard] => image1,image2,image3 )
print_r($row);

// Turn Array into String
    // if you use $row you get - Piece 0 = i

        $wordChunks = implode(',', $row);
for($i = 0; $i < count($wordChunks); $i++){
        echo "Piece $i = $wordChunks[$i] <br />";
            }



}


This is what I get using that code - Array ( [wizard] => image1,image2,image3 ) Piece 0 = i

Not sure what to do now...

emanuele

Quote from: The Wizard on August 23, 2012, 11:12:47 AM
Not sure what to do now...
Read my entire post? :P

Quote from: emanuele on August 23, 2012, 10:47:26 AM

        $wordChunks = implode(',', $row);

implode convert an array to a string, what you should do here is convert a string into an array, so you should use explode. ;)


Take a peek at what I'm doing! ;D




Hai bisogno di supporto in Italiano?

Aiutateci ad aiutarvi: spiegate bene il vostro problema: no, "non funziona" non è una spiegazione!!
1) Cosa fai,
2) cosa ti aspetti,
3) cosa ottieni.

The Wizard

Emanuele I finally got it! Thanks again for all the help. I learned allot, and I know I still have a way to go. Below is my cleaned up code. Please have a look and see if I made any mistakes.

Wiz

function onUse()
{
global $smcFunc, $db_prefix, $user_info;

// Get the user's information from the database

    $result = $smcFunc['db_query']('', "
    SELECT wizard
    FROM {db_prefix}members
    WHERE id_member = {int:current_member}
    LIMIT 1",
    array(
      'current_member' => $user_info['id'],
    ));

    // fetch their information

$row = $smcFunc['db_fetch_assoc']($result);

// do an implode on the array - now the array is a text string with the values seprated by commas

    $W = implode(',', $row);

// add your value to the array - in this case its image12

    $B = $W . (!empty($W) ? ',' : '') . 'image12';

// Save all the orginal image names plus the new value

    updateMemberData($user_info['id'], array('wizard' => $B));

    return '<br>You now own 12 long-stem roses.<br /><br />We here at Acme Florists division hopes that they will brighten your day.<br />
    <br />Enjoy<br />
        <br />Acme Division Products Company<br /><br />';

}

emanuele

Why do you want to implode it at all costs?
You don't need to! ;)


$W = implode(',', $row);

That piece is just useless: $row is yes an array (apart that you could even retrieve it as a simple string, but that's for later :)), but if you use $row['wizard'] you'll obtain the string without have to implode anything.
So:
function onUse()
{
global $smcFunc, $db_prefix, $user_info;

// Get the user's information from the database

    $result = $smcFunc['db_query']('', "
    SELECT wizard
    FROM {db_prefix}members
    WHERE id_member = {int:current_member}
    LIMIT 1",
    array(
      'current_member' => $user_info['id'],
    ));

    // fetch their information

$row = $smcFunc['db_fetch_assoc']($result);

// add your value to the array - in this case its image12

    $B = $row['wizard'] . (!empty($row['wizard']) ? ',' : '') . 'image12';

// Save all the orginal image names plus the new value

    updateMemberData($user_info['id'], array('wizard' => $B));

    return '<br>You now own 12 long-stem roses.<br /><br />We here at Acme Florists division hopes that they will brighten your day.<br />
    <br />Enjoy<br />
        <br />Acme Division Products Company<br /><br />';

}


Take a peek at what I'm doing! ;D




Hai bisogno di supporto in Italiano?

Aiutateci ad aiutarvi: spiegate bene il vostro problema: no, "non funziona" non è una spiegazione!!
1) Cosa fai,
2) cosa ti aspetti,
3) cosa ottieni.

Advertisement: