Solved

How to pull out data from array?

Posted on 2014-04-25
19
586 Views
Last Modified: 2014-05-30
I'm trying to pull data out to insert into database from the following link:
http://bit.ly/PBIgJI

How can I call different fields like "text" and other elements?
0
Comment
Question by:N R
  • 7
  • 6
  • 5
  • +1
19 Comments
 
LVL 34

Expert Comment

by:Dan Craciun
ID: 40024075
That looks like the output of a var_dump command.

If that's the case, you aren't supposed to import that.
Use serialize or, better, json_encode.

HTH,
Dan
0
 
LVL 54

Expert Comment

by:Julian Hansen
ID: 40024183
Should be fairly simple
$input = 'http://bit.ly/PBIgJI';
$input = file_get_contents($input);
parse_str($input, $output);

Open in new window

$output should contain the parsed info.
0
 
LVL 54

Expert Comment

by:Julian Hansen
ID: 40024190
Belay that - might not work 100% ... working on another approach.
0
Best Practices: Disaster Recovery Testing

Besides backup, any IT division should have a disaster recovery plan. You will find a few tips below relating to the development of such a plan and to what issues one should pay special attention in the course of backup planning.

 
LVL 54

Assisted Solution

by:Julian Hansen
Julian Hansen earned 250 total points
ID: 40024301
Here is some code I knocked together that should be able to parse that file into an internal object.
Change the SOURCE define to point to the URL (or file) where the dump comes from
Then call the parse_file function.
The URL you gave returns the dumps of multiple objects. The code below will handel that. The return from parse_file is an array of parsed objects.
There is one hiccough - the dumped data has a line break in a string at around line 1269 which sort of messes up the parser. I hacked a solution to append the next line but to make this work I needed to strip the \n from the current line so the preg_match would match the line - this results in a short count on the string length and the loss of the \n in the string - working on a fix.
<pre>
<?php
define('SOURCE', 'vardump.txt');

function & parse_file()
{
  $object = array();
  while(($item = parse_item()) != null){
    $object[] = $item;
  }
  return $object;
}

function & parse_item()
{
  $object = null;
  $l = get_line();
  if ($l != null) {
    $type = preg_match('/([a-zNULL]+).*/', $l, $r);
    switch($r[1]) {
    case 'array' :
      $object = parse_array($l);
    break;
    case 'object' :
      $object = parse_object($l);
    break;
    default:
      $object = parse_simple($l);
    break;
    }
  }
  return $object;
}

function & get_line($trimstr = true)
{
  static $lines = null;
  if ($lines == null) {
    $input = file_get_contents(SOURCE);
    $lines = explode("\n", $input);
  }
  
  $l = empty($lines) ? array() : array_shift($lines);
  if ($trimstr) $l = trim($l);

  return $l;
}

function parse_array(&$l)
{
  $object = array();
  $dt = preg_match('/^array\((\d+)\)\s+{$/', $l, $r);

  if (isset($r[1])) {
    while(($l = get_line()) != '}') {
      $d2 = preg_match('/^\[(.+)\]=>$/', $l, $r1);
      if (isset($r1[1])) {
        $object[$r1[1]] = parse_item();
      }
      else {
        echo "Error: Array mismatch on index\n";
      }
    }
  }
  else {
    echo "Error: Array mismatch\n";
  }
  return $object;
}

function parse_object(&$l)
{
  $object = new stdClass;
  $dt = preg_match('/^object\((.+)\)#(\d+)\s+\((\d+)\)\s+{$/', $l, $r);
  if (isset($r[1])) {
    while(($l = get_line()) != '}') {
      $d2 = preg_match('/^\[(.+)\]=>$/', $l, $r1);
      if (isset($r1[1])) {
        $object->{$r1[1]} = parse_item();
      }
      else {
        echo "Error: Object mismatch on index\n";
      }
    }
  }
  else {
    echo "Error: Object mismatch\n";
  }
  return $object;
}

function parse_simple(&$l)
{
  $object = '';
  $ss = substr($l, 0, 3);
  switch($ss) {
    case 'str' :
      preg_match('/^string\((\d+)\)\s+"(.*)"$/', $l, $r);
      $count = 0;
      while (!isset($r[1]) && $count++ < 5) {
        $l .= get_line();
        preg_match('/^string\((\d+)\)\s+"(.*)"$/', $l, $r);
      }
      $object = isset($r[2]) ? $r[2] : 'STRING: error';
      if (($len = strlen($object)) != $r[1]) {
        echo "Error: string length. Expected [{$r[1]}] Actual[{$len}]\n";
      }
    break;
    case 'int' :
      $dt = preg_match('/^int\((\d+)\)$/', $l, $r);
      $object = (int)(empty($r[1])?0:$r[1]);
    break;
    case 'boo' :
      $dt = preg_match('/^bool\((false|true)\)$/', $l, $r);
      $object = (bool)(empty($r[1]) ? false : $r[1]);
    break;
    case 'flo' :
      $dt = preg_match('/^float\((\d+\.\d+)\)$/', $l, $r);
      $object = (float)(empty($r[1])?0:$r[1]);
    break;
    case 'NUL':
      $object = null;
    break;
    default:
      echo "Don't know what this is {$ss}\n";
    break;
  }
  return $object;
}

$res = parse_file();
print_r($res);
?>
</pre>

Open in new window

0
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 40024566
trying to pull data out
You'll get a more specific answer if you do these two things.

1. Tell us what data you want.  Each of the 15 Tweets in this stream contains some data elements that are useful and probably some that are not.  Give us the names of the fields you would like to extract.

2. Give us access to the original data, not a var_dump() representation of the data.  Var_Dump() output is useful for visualization and debugging, but we need the original data if we are going to show you the correct programmatic way to access the information in the Tweets.  

The original was probably a JSON string (because that's what everybody uses for API output today) but it might have been an XML document.  In either case, there is a PHP function for dealing with the original data.  A programmer would use SimpleXML_Load_String() or JSON_Decode().  Either of those functions will make an object that can be iterated with foreach().
0
 
LVL 11

Author Comment

by:N R
ID: 40024592
@julian - can I use this against the data that's pulled via a php file instead of .txt?

@Ray - Sure thing the line used to pull the data:
$result = $twitter->search_tweets('q=#'.$q.'&include_entities='.false.'&result_type=recent', false);

Open in new window


It's part of codebird library to pull twitter tweets.  The reason I'm trying to modify is the default setup doesn't seem to pull in tweets that I'm searching for via hashtags.  Here is my code as well if that helps:

<?php
require_once __DIR__.'/../includes.php';

/* TWITTER OBJECT */
\Codebird\Codebird::setConsumerKey(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET); // static, see 'Using multiple Codebird instances'

$twitter = \Codebird\Codebird::getInstance();

$twitter->setToken(TWITTER_ACCESS_TOKEN, TWITTER_TOKEN_SECRET);

/* QUERY -- used in facebook, twitter, and instagram searching */
$q = 'americancrew';


/*  GET TWITTER POSTS */

$result = $twitter->search_tweets('q=#'.$q.'&include_entities='.false.'&result_type=recent', false);
//$result = $twitter->statuses_userTimeline('screen_name='.urlencode(TWITTER_SCREEN_NAME));

//var_dump($result);

if (isset($result)) {
	
	$statuses = (array)$result;
		
	if (is_array($statuses)) {
	
		foreach ($statuses as $tweet) {
			
			if (!empty($tweet->text)) {
				
				$text = $tweet->text;
				
				
				$added_chars = 0;
				
				if (!empty($tweet->entities->media) && is_array($tweet->entities->media)) {
					
					foreach ($tweet->entities->media as $media) {
						
						if (!empty($media->url)) {
						
							$url = '<a href="'.$media->url.'" target="_blank">'.$media->url.'</a>';
							
							$text = str_replace($url, $media->url, $text);							
							$text = str_replace($media->url, $url, $text);	
						}
					}	
				}	
				
				if (!empty($tweet->entities->urls) && is_array($tweet->entities->urls)) {
					
					foreach ($tweet->entities->urls as $url_obj) {
						
						if (!empty($url_obj->url)) {
						
							$url = '<a href="'.$url_obj->url.'" target="_blank">'.$url_obj->url.'</a>';
					
							$text = str_replace($url, $url_obj->url, $text);						
							$text = str_replace($url_obj->url, $url, $text);	
	
						}
					}	
				}
				
				if (!empty($tweet->entities->user_mentions) && is_array($tweet->entities->user_mentions)) {
					
					foreach ($tweet->entities->user_mentions as $user) {
						
						if (!empty($user->screen_name)) {
						
							$url = '<a href="http://twitter.com/'.$user->screen_name.'" target="_blank">@'.$user->screen_name.'</a>';
							
							$text = str_replace('@'.$user->screen_name, $url, $text);	
		
						}
					}	
				}
				
				if (!empty($tweet->entities->hashtags) && is_array($tweet->entities->hashtags)) {
					
					foreach ($tweet->entities->hashtags as $hashtag) {
						
						if (!empty($hashtag->text)) {
						
							$url = '<a href="http://twitter.com/search?q=%23'.$hashtag->text.'" target="_blank">#'.$hashtag->text.'</a>';
							
							$text = str_replace('#'.$hashtag->text, $url, $text);	
		
						}
					}	
				}				
						
				
				$insert = array();
				$insert['source'] = SOURCE_TWITTER;
				$insert['source_id'] = SOURCE_TWITTER.'_'.$tweet->id_str;
				$insert['text'] = $text;
				$insert['type'] = 'text';
				//$insert['media_thumbnail_url'];
				//$insert['media_url'];
				$insert['author'] = $tweet->user->name;
	
				if (!empty($tweet->user->screen_name)) {
					
					$insert['author_url'] = 'http://twitter.com/'.$tweet->user->screen_name;
				}
	
				
				if (is_numeric($tweet->created_at)) {
					$post_date = intval($tweet->created_at);	
				} else {
					$post_date = strtotime($tweet->created_at);	
				}
				
				$insert['post_date'] = date("Y-m-d H:i:s", $post_date);			
				$insert['date_added'] = date("Y-m-d H:i:s");
				$insert['date_updated'] = $insert['date_added'];
	
				$db->insert('posts', $insert);				
				
				
			}			
			
		}
		
	}
	
}

Open in new window

0
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 40024595
So the thing we were looking at here (http://bit.ly/PBIgJI) was the output of var_dump($result); right?

In order to access the twitter feed, we would need the information in the included files, including the Codebird stuff.

Without access to the Twitter feed, it is impossible to test a solution, but we may be able to get you some examples.
0
 
LVL 11

Author Comment

by:N R
ID: 40024601
Yes correct.  I tried echoing out, but just received an error, I assume b/c it's an array.
0
 
LVL 54

Expert Comment

by:Julian Hansen
ID: 40024602
can I use this against the data that's pulled via a php file instead of .txt?

Yes - if your ISP supports it you can simply change the

define('SOURCE','vardump.txt');

To

define('SOURCE','http://bit.ly/PBIgJI');

Some ISP's disable the ability to use file_get_contents to load remote pages - if so you would then need to look at the cURL library to pull the data.

Either way - all that is required is to load the file into the $input variable in the get_line function.
0
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 40024604
My guess is that it's an object, not an array.  What did you see when you tried echo?
0
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 40024607
Also, what is the definition of this method?  What does the FALSE argument mean?  Have you tried constructing the input argument separately (not loading it into the function call) so you can see what is being sent to the method?

$result = $twitter->search_tweets('q=#'.$q.'&include_entities='.false.'&result_type=recent', false);
0
 
LVL 11

Author Comment

by:N R
ID: 40024608
@Ray - Catchable fatal error: Object of class stdClass could not be converted to string in /home/convo/public_html/americancrew/cron/pull-twitter1.php on line 19
0
 
LVL 11

Author Comment

by:N R
ID: 40024611
I'm not familiar with the code.  I'm not sure what false/true means in that statement and unsure where to go to find how it works.  I assume it has something to do with codebird?  I can attach the source file.
codebird.php
0
 
LVL 109

Expert Comment

by:Ray Paseur
ID: 40024613
OK, that's useful information.  It means that $result should be iteratable in its existing state.  In other words, the API call has already converted the JSON or XML string into a PHP object.
0
 
LVL 11

Author Comment

by:N R
ID: 40024625
@julian that appears to work without errors, here is the output:
http://conversationdevelopment.com/americancrew/cron/nathan.php

I'm wondering now in that page after you functions how I would call each field like:
created_at
id
text
source
user
url
entities

Take those and get them ready to insert into my database.  I know you said you saw some nuances above is this a viable solution for this or is there a better solution?
0
 
LVL 54

Expert Comment

by:Julian Hansen
ID: 40024670
Once you run that code the data is now in a standard PHP structure - an array of objects that contain the data.

The dump is actually of 3 objects so the returned array will contain each of these in postions 0 through 2.

To access the first we can do like so
$status = $object[0];

echgo $status['statuses'][0]->id'

Open in new window

0
 
LVL 109

Accepted Solution

by:
Ray Paseur earned 250 total points
ID: 40024717
Try it like this:

<?php // temp_gallitin.php

/**
 * SEE: http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28420533.html
 */
 
error_reporting(E_ALL);
require_once __DIR__.'/../includes.php';

/* SINGLETON TWITTER OBJECT */
\Codebird\Codebird::setConsumerKey(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET); // static, see 'Using multiple Codebird instances'
$twitter = \Codebird\Codebird::getInstance();
$twitter->setToken(TWITTER_ACCESS_TOKEN, TWITTER_TOKEN_SECRET);

//  GET TWITTER POSTS IN THE FORM OF A PHP OBJECT OF StdClass
$arg = 'q=#americancrew&include_entities=&result_type=recent';
$obj = $twitter->search_tweets($arg, false);
if (!$obj) trigger_error("TWITTER FAIL WITH $arg", E_USER_ERROR);

// USE THE ITERATOR TO ACCESS PROPERTIES OF THE OBJECT
foreach ($obj->statuses as $sta)
{
    $ca = $sta->created_at;
    $tx = $sta->text;
    $un = $sta->user->name;
    $lo = $sta->user->location;

    // SHOW SOME DATA
    echo PHP_EOL . '<br>';
    echo "ON $ca, $un OF $lo TWEETED: $tx";
}

Open in new window

Best regards, ~Ray
0
 
LVL 11

Author Comment

by:N R
ID: 40025082
Seems to only pull the most recent 15.  Any ideas on where I could increase that limit?  I don't show anything limiting it in your code.
0
 
LVL 11

Author Comment

by:N R
ID: 40101820
This was a good solution Ray, the only thing missing from the array in your solution is the "media_url" if a picture is posted it would pull that URL as well as shown in the var_dump, but not is your $sta array.
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

These days socially coordinated efforts have turned into a critical requirement for enterprises.
This article discusses four methods for overlaying images in a container on a web page
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to dynamically set the form action using jQuery.

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question