Solved

How to pull out data from array?

Posted on 2014-04-25
19
570 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 51

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 51

Expert Comment

by:Julian Hansen
ID: 40024190
Belay that - might not work 100% ... working on another approach.
0
 
LVL 51

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 108

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 108

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 51

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
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 108

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 108

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 108

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 51

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 108

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

Easy Project Management (No User Manual Required)

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

747 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now