Viewed   167 times

Using the following code to display a list of friends from my twitter profile. Id like to only load a certain number at a time, say 20, then provide pagination links at the bottom for First 1-2-3-4-5(however many divided by limit) Last

$xml = simplexml_load_string($rawxml);

foreach ($xml->id as $key => $value) 
{
    $profile           = simplexml_load_file("https://twitter.com/users/$value");
    $friendscreenname  = $profile->{"screen_name"};
    $profile_image_url = $profile->{"profile_image_url"};

    echo "<a href=$profile_image_url>$friendscreenname</a><br>";
}

******update******

if (!isset($_GET['i'])) {
    $i = 0;
} else {
    $i = (int) $_GET['i'];
}

$limit  = $i + 10;
$rawxml = OauthGetFriends($consumerkey, $consumersecret, $credarray[0], $credarray[1]);
$xml    = simplexml_load_string($rawxml);

foreach ($xml->id as $key => $value)
{

    if ($i >= $limit) {
        break;
    }

    $i++;
    $profile           = simplexml_load_file("https://twitter.com/users/$value");
    $friendscreenname  = $profile->{"screen_name"};
    $profile_image_url = $profile->{"profile_image_url"};

    echo "<a href=$profile_image_url>$friendscreenname</a><br>";
}

echo "<a href=step3.php?i=$i>Next 10</a><br>";

This works, just have to offset the output starting at $i. Thinking array_slice?

 Answers

4

A very elegant solution is using a LimitIterator:

$xml = simplexml_load_string($rawxml);
// can be combined into one line
$ids = $xml->xpath('id'); // we have an array here
$idIterator = new ArrayIterator($ids);
$limitIterator = new LimitIterator($idIterator, $offset, $count);
foreach($limitIterator as $value) {
    // ...
}

// or more concise
$xml = simplexml_load_string($rawxml);
$ids = new LimitIterator(new ArrayIterator($xml->xpath('id')), $offset, $count);
foreach($ids as $value) {
    // ...
}
Monday, September 12, 2022
3

So basically what you need to do is a function that takes each <asset/> child of current node, builds the HTML then checks if the current node has <asset/> children of its own and keeps recursing deeper down the tree.

Here's how you can do it:

function printAssetMap()
{
    return printAssets(simplexml_load_file(X_ASSETS));
}

function printAssets(SimpleXMLElement $parent)
{
    $html = "<ul>n";
    foreach ($parent->asset as $asset)
    {
        $html .= printAsset($asset);
    }
    $html .= "</ul>n";

    return $html;
}

function printAsset(SimpleXMLElement $asset)
{
    $html = '<li id="asset'.$asset->asset_assetid.'"><ins>&nbsp;</ins><a href="#">'.$asset->asset_name.' ['.$asset->asset_assetid.']</a>';

    if (isset($asset->asset))
    {
        // has <asset/> children
        $html .= printAssets($asset);
    }

    $html .= "</li>n";

    return $html;
}

By the way, I would expect a function named "printX" to actually print or echo something, rather than return it. Perhaps you should name those functions "buildX" ?

Saturday, September 17, 2022
 
shdr
 
2

You can use continue to skip the current iteration of a loop.

$exclude = array(3, 4, 8, 19);

for ($i=1; $i<=27; $i++)
{
    if (in_array($i, $exclude)) continue;
    echo "<option value=$i>$i</option>";
}

Documentation.

Friday, August 5, 2022
 
spinon
 
3

For using await keyword you need to define the function with async keyword, e.g.

users.forEach(async (user) => {
  await check(user)
    .then((result) => {
      console.log(result);
    });
  })

However this code is most likely not the thing you want as it is going to fire async calls without waiting for them to finish (Using async/await with a forEach loop)

To make it properly you can use Promise.all, e.g.

Promise.all(users.map(check)).then((results) => {
  //results is array of all promise results, in your case it should be
  // smth like [res, false|null|undefined, res, ...]
})
Monday, November 21, 2022
 
kenumir
 
4

Happily, if SimpleXML doesn't support those DOM-methods, it supports XPath, with the SimpleXMLElement::xpath() method.

And searching by tag name or id, with an XPath query, shouldn't be too hard.
I suppose queries like theses should do the trick :

  • search by id : //*[@id='VALUE']
  • search by tag name : //TAG_NAME



For example, with the following portion of XML and code to load it :

$str = <<<STR
<xml>
    <a id="plop">test id</a>
    <b>hello</b>
    <a>a again</a>
</xml>
STR;
$xml = simplexml_load_string($str);

You could find one element by its id="plop" with something like this :

$id = $xml->xpath("//*[@id='plop']");
var_dump($id);

And search for all <a> tags with that :

$as = $xml->xpath("//a");
var_dump($as);

And the output would be the following one :

array
  0 => 
    object(SimpleXMLElement)[2]
      public '@attributes' => 
        array
          'id' => string 'plop' (length=4)
      string 'test id' (length=7)

array
  0 => 
    object(SimpleXMLElement)[3]
      public '@attributes' => 
        array
          'id' => string 'plop' (length=4)
      string 'test id' (length=7)
  1 => 
    object(SimpleXMLElement)[4]
      string 'a again' (length=7)
Saturday, October 1, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :