Avatar of JohnLourdu
JohnLourduFlag for Afghanistan asked on

how to delete matched row of json file using php

Hi experts,

I need to delete specific row of json file using php. Below is my code in DelBookLibrary.php:

   $jsonfpath = "epub_content/epub_library.json";
   $input = file_get_contents($jsonfpath);
   $json = json_decode($input,true);
   $match = array('url_to_package_doc'=>'epub_content/moby-dick-20120118/OPS/package.opf', 'title'=>'moby-dick-20120118');
   $upload_info = unset($json['library_epubs'][array_search($match,$json['library_epubs'])]);
   file_put_contents($jsonfpath,json_encode($json,JSON_UNESCAPED_SLASHES));

my json file epub_library.json is:

{"library_epubs":[{"title":"Page Blanche","url_to_package_doc":"epub_content/page-blanche/EPUB/package.opf","cover_path":"epub_content/page-blanche/EPUB/Image/cover.jpg"},{"title":"Moby Dick","url_to_package_doc":"epub_content/moby_dick/OPS/package.opf","cover_path":"epub_content/moby_dick/OPS/images/9780316000000.jpg"},{"title":"moby-dick-20120118","url_to_package_doc":"epub_content/moby-dick-20120118/OPS/package.opf","cover_path":"epub_content/moby-dick-20120118/OPS/images/9780316000000.jpg"}]}

But I have got below mentioned error:

Parse error: syntax error, unexpected 'unset' (T_UNSET) in /var/www/epubapp/LoginSystem/DelBookLibrary.php on line 40

Please advice.

Regards,
John.A
PHPWeb Languages and Standards

Avatar of undefined
Last Comment
JohnLourdu

8/22/2022 - Mon
Ray Paseur

A PHP parse error that says "unexpected" usually means that something is wrong upstream.   It's often a missing semi-colon or unmatched parentheses.  Since the error is noted on line 40, we would expect to see 40 lines of code.
Ray Paseur

I'll try to walk you through this in the way a professional would probably tackle the problem.  From this and your other question, it seems to me that you would benefit from taking some time to get a foundation in how PHP works.  This article will be helpful if you want to do that.
https://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_11769-And-by-the-way-I-am-new-to-PHP.html

The first thing that would be important would be data visualization.  We've got to see exactly what we're dealing with.  This script takes us forward.

<?php // RAY_temp_johnlourdu.php
error_reporting(E_ALL);
echo '<pre>';

// PARSE A JSON STRING
// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28223470.html

// CREATE THE JSON STRING USING HEREDOC NOTATION
$jso = <<<EOD
{"library_epubs":[{"title":"Page Blanche","url_to_package_doc":"epub_content/page-blanche/EPUB/package.opf","cover_path":"epub_content/page-blanche/EPUB/Image/cover.jpg"},{"title":"Moby Dick","url_to_package_doc":"epub_content/moby_dick/OPS/package.opf","cover_path":"epub_content/moby_dick/OPS/images/9780316000000.jpg"},{"title":"moby-dick-20120118","url_to_package_doc":"epub_content/moby-dick-20120118/OPS/package.opf","cover_path":"epub_content/moby-dick-20120118/OPS/images/9780316000000.jpg"}]}
EOD;

$obj = JSON_Decode($jso);
var_dump($jso);
var_dump($obj);

Open in new window

Ray Paseur

Next, we will want to use an iterator so we can see and test each internal object.  We will be looking at the $epub variable in the output of this script.

<?php // RAY_temp_johnlourdu.php
error_reporting(E_ALL);
echo '<pre>';

// PARSE A JSON STRING
// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28223470.html

// CREATE THE JSON STRING USING HEREDOC NOTATION
$jso = <<<EOD
{"library_epubs":[{"title":"Page Blanche","url_to_package_doc":"epub_content/page-blanche/EPUB/package.opf","cover_path":"epub_content/page-blanche/EPUB/Image/cover.jpg"},{"title":"Moby Dick","url_to_package_doc":"epub_content/moby_dick/OPS/package.opf","cover_path":"epub_content/moby_dick/OPS/images/9780316000000.jpg"},{"title":"moby-dick-20120118","url_to_package_doc":"epub_content/moby-dick-20120118/OPS/package.opf","cover_path":"epub_content/moby-dick-20120118/OPS/images/9780316000000.jpg"}]}
EOD;

$obj = JSON_Decode($jso);
// var_dump($jso);
// var_dump($obj);

// USE AN ITERATOR TO ACCESS THE INTERNAL OBJECTS
foreach ($obj->library_epubs as $epub)
{
    var_dump($epub);
}

Open in new window

Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
Ray Paseur

Let's see if we can match the title of the object we want to delete.  If we get a match, we will print that object.

<?php // RAY_temp_johnlourdu.php
error_reporting(E_ALL);
echo '<pre>';

// PARSE A JSON STRING
// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28223470.html

// CREATE THE JSON STRING USING HEREDOC NOTATION
$jso = <<<EOD
{"library_epubs":[{"title":"Page Blanche","url_to_package_doc":"epub_content/page-blanche/EPUB/package.opf","cover_path":"epub_content/page-blanche/EPUB/Image/cover.jpg"},{"title":"Moby Dick","url_to_package_doc":"epub_content/moby_dick/OPS/package.opf","cover_path":"epub_content/moby_dick/OPS/images/9780316000000.jpg"},{"title":"moby-dick-20120118","url_to_package_doc":"epub_content/moby-dick-20120118/OPS/package.opf","cover_path":"epub_content/moby-dick-20120118/OPS/images/9780316000000.jpg"}]}
EOD;

$obj = JSON_Decode($jso);
// var_dump($jso);
// var_dump($obj);


// IDENTIFY THE SIGNAL STRING FOR DELETION
$sig = 'moby-dick-20120118';

// USE AN ITERATOR TO ACCESS THE INTERNAL OBJECTS
foreach ($obj->library_epubs as $key => $epub)
{
    // IF THE TITLE MATCHES THE SIGNAL STRING
    if ($epub->title == $sig)
    {
        print_r($epub);
    }
}

Open in new window

Ray Paseur

Now that we know we can iterate over the object and match the properties to our signal string, the next step will be to modify the object by deleting one of the internal objects.  This code will attempt that deletion and will show us the object after the deletion, so we can check to see if it looks right.

<?php // RAY_temp_johnlourdu.php
error_reporting(E_ALL);
echo '<pre>';

// PARSE A JSON STRING
// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28223470.html

// CREATE THE JSON STRING USING HEREDOC NOTATION
$jso = <<<EOD
{"library_epubs":[{"title":"Page Blanche","url_to_package_doc":"epub_content/page-blanche/EPUB/package.opf","cover_path":"epub_content/page-blanche/EPUB/Image/cover.jpg"},{"title":"Moby Dick","url_to_package_doc":"epub_content/moby_dick/OPS/package.opf","cover_path":"epub_content/moby_dick/OPS/images/9780316000000.jpg"},{"title":"moby-dick-20120118","url_to_package_doc":"epub_content/moby-dick-20120118/OPS/package.opf","cover_path":"epub_content/moby-dick-20120118/OPS/images/9780316000000.jpg"}]}
EOD;

$obj = JSON_Decode($jso);
// var_dump($jso);
// var_dump($obj);


// IDENTIFY THE SIGNAL STRING FOR DELETION
$sig = 'moby-dick-20120118';

// USE AN ITERATOR TO ACCESS THE INTERNAL OBJECTS
foreach ($obj->library_epubs as $key => $epub)
{
    // IF THE TITLE MATCHES THE SIGNAL STRING
    if ($epub->title == $sig)
    {
        // REMOVE THIS OBJECT
        unset($obj->library_epubs[$key]);
    }
}

// DID THE DELETION WORK CORRECTLY?
var_dump($obj);

Open in new window

ASKER CERTIFIED SOLUTION
Ray Paseur

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
See how we're fighting big data
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
ASKER
JohnLourdu

Hi Ray,

Thanks for your detailed help. I have updated your code to my php as below. But still problem exists. Please advice.

DelBookLibrary.php

<?php

$curDelFol=$_POST['curDelFol'];
$curDelFile=$_POST['curDelFile'];
$curDelFileTitle=$_POST['curDelFileTitle'];

echo $curDelFol;
echo $curDelFile;
echo $curDelFileTitle;

function deleteDir($dir) {
   // open the directory
   $dhandle = opendir($dir);

   if ($dhandle) {
      // loop through it
      while (false !== ($fname = readdir($dhandle))) {
         // if the element is a directory, and
         // does not start with a '.' or '..'
         // we call deleteDir function recursively
         // passing this element as a parameter
         if (is_dir( "{$dir}/{$fname}" )) {
            if (($fname != '.') && ($fname != '..')) {
               //echo "<u>Deleting Files in the Directory</u>: {$dir}/{$fname} <br />";
               deleteDir("$dir/$fname");
            }
         // the element is a file, so we delete it
         } else {
            //echo "Deleting File: {$dir}/{$fname} <br />";
            unlink("{$dir}/{$fname}");
         }
      }
      closedir($dhandle);
    }
   // now directory is empty, so we can use
   // the rmdir() function to delete it
   //echo "<u>Deleting Directory</u>: {$dir} <br />";
   rmdir($dir);

$jso = file_get_contents("epub_content/epub_library.json");
$obj = JSON_Decode($jso);
 //var_dump($jso);
 //var_dump($obj);

// IDENTIFY THE SIGNAL STRING FOR DELETION
$sig = $curDelFileTitle;

// USE AN ITERATOR TO ACCESS THE INTERNAL OBJECTS
foreach ($obj->library_epubs as $key => $epub)
{
    // IF THE TITLE MATCHES THE SIGNAL STRING
    if ($epub->title == $sig)
    {
        // REMOVE THIS OBJECT
        unset($obj->library_epubs[$key]);
    }
}

// DID THE DELETION WORK CORRECTLY?
// YES, IT WORKED. var_dump($obj);

// CREATE A NEW JSON STRING FROM THE OBJECT
$new = json_encode($obj, JSON_UNESCAPED_SLASHES);
var_dump($new);
file_put_contents("epub_content/epub_library.json",$new);
   
   //header("location:bkself/shelf.php");
}

// call deleteDir function and pass to it
// as a parameter a directory name
deleteDir($curDelFol);


?>

shelf.php

<form class="hidden" id="delfile_form" method="post" action="../DelBookLibrary.php">
<input type="text" value="" id="curDelFol" name="curDelFol"/>
<input type="text" value="" id="curDelFile" name="curDelFile"/>
<input type="text" value="" id="curDelFileTitle" name="curDelFileTitle"/>
<input type="submit" value="submit"/>
</form>

Regards,
John.A
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER
JohnLourdu

Hi Ray,

Please forgive my unfamiliar of programming. This is my mistake. I have declared variable in out of the function. I have corrected this as below. It works fine.

<?php

$curDelFol=$_POST['curDelFol'];
$curDelFile=$_POST['curDelFile'];
$curDelFileTitle=$_POST['curDelFileTitle'];

//echo $curDelFol;
//echo $curDelFile;
//echo $curDelFileTitle;

function deleteDir($dir) {
   // open the directory
   $dhandle = opendir($dir);

   if ($dhandle) {
      // loop through it
      while (false !== ($fname = readdir($dhandle))) {
         // if the element is a directory, and
         // does not start with a '.' or '..'
         // we call deleteDir function recursively
         // passing this element as a parameter
         if (is_dir( "{$dir}/{$fname}" )) {
            if (($fname != '.') && ($fname != '..')) {
               //echo "<u>Deleting Files in the Directory</u>: {$dir}/{$fname} <br />";
               deleteDir("$dir/$fname");
            }
         // the element is a file, so we delete it
         } else {
            //echo "Deleting File: {$dir}/{$fname} <br />";
            unlink("{$dir}/{$fname}");
         }
      }
      closedir($dhandle);
    }
   // now directory is empty, so we can use
   // the rmdir() function to delete it
   //echo "<u>Deleting Directory</u>: {$dir} <br />";
   rmdir($dir);

$jso = file_get_contents("epub_content/epub_library.json");
$obj = JSON_Decode($jso);
 //var_dump($jso);
 //var_dump($obj);

// IDENTIFY THE SIGNAL STRING FOR DELETION
$sig = $_POST['curDelFileTitle'];

// USE AN ITERATOR TO ACCESS THE INTERNAL OBJECTS
foreach ($obj->library_epubs as $key => $epub)
{
    // IF THE TITLE MATCHES THE SIGNAL STRING
    if ($epub->title == $sig)
    {
        // REMOVE THIS OBJECT
        unset($obj->library_epubs[$key]);
    }
}

// DID THE DELETION WORK CORRECTLY?
// YES, IT WORKED. var_dump($obj);

// CREATE A NEW JSON STRING FROM THE OBJECT
$new = json_encode($obj, JSON_UNESCAPED_SLASHES);
//var_dump($new);
file_put_contents("epub_content/epub_library.json",$new);
header("location:bkself/shelf.php");
}

// call deleteDir function and pass to it
// as a parameter a directory name
deleteDir($curDelFol);


?>

Thanks for your detailed help.

Regards,
John.A
Ray Paseur

Glad it worked for you, and thanks for the points.

Going forward, when you post code here at EE, please use the "code" feature.  It gives us a unispace font and line numbers, and it facilitates copy/paste operations.  Just click the word "code" in the gray bar at the top of the comment area, and paste your code in between the BBCode tags.  Easy!  Example here:
<?php

$curDelFol=$_POST['curDelFol'];
$curDelFile=$_POST['curDelFile'];
$curDelFileTitle=$_POST['curDelFileTitle'];

//echo $curDelFol;
//echo $curDelFile;
//echo $curDelFileTitle;

function deleteDir($dir) {
   // open the directory
   $dhandle = opendir($dir);

   if ($dhandle) {
      // loop through it
      while (false !== ($fname = readdir($dhandle))) {
         // if the element is a directory, and
         // does not start with a '.' or '..'
         // we call deleteDir function recursively
         // passing this element as a parameter
         if (is_dir( "{$dir}/{$fname}" )) {
            if (($fname != '.') && ($fname != '..')) {
               //echo "<u>Deleting Files in the Directory</u>: {$dir}/{$fname} <br />";
               deleteDir("$dir/$fname");
            }
         // the element is a file, so we delete it
         } else {
            //echo "Deleting File: {$dir}/{$fname} <br />";
            unlink("{$dir}/{$fname}");
         }
      }
      closedir($dhandle);
    }
   // now directory is empty, so we can use
   // the rmdir() function to delete it
   //echo "<u>Deleting Directory</u>: {$dir} <br />";
   rmdir($dir);

$jso = file_get_contents("epub_content/epub_library.json");
$obj = JSON_Decode($jso);
 //var_dump($jso);
 //var_dump($obj);

// IDENTIFY THE SIGNAL STRING FOR DELETION
$sig = $_POST['curDelFileTitle'];

// USE AN ITERATOR TO ACCESS THE INTERNAL OBJECTS
foreach ($obj->library_epubs as $key => $epub)
{
    // IF THE TITLE MATCHES THE SIGNAL STRING
    if ($epub->title == $sig)
    {
        // REMOVE THIS OBJECT
        unset($obj->library_epubs[$key]);
    }
}

// DID THE DELETION WORK CORRECTLY?
// YES, IT WORKED. var_dump($obj);

// CREATE A NEW JSON STRING FROM THE OBJECT
$new = json_encode($obj, JSON_UNESCAPED_SLASHES);
//var_dump($new);
file_put_contents("epub_content/epub_library.json",$new);
header("location:bkself/shelf.php");
}

// call deleteDir function and pass to it
// as a parameter a directory name
deleteDir($curDelFol);

Open in new window

Now with that said, I think you might want to get some formal training in how PHP works.  I have an article here at EE that can lead you to some good learning resources.  I say this because of the header() function call on line 66.  That instruction is obviously intended to redirect the client browser.  But header() is a synchronous statement.  The header will be sent to the browser, and the PHP script will keep right on running!  The only thing you do not know is how long the PHP script will keep running.  After the browser receives the header, it will make the redirect and it may send a "stop" signal to this script.  But those events are in the future and may be timing dependent - internet traffic can cause a time delay.  Your script will have continued to run for some period of time -- you just don't know how much time.

The usual approach to this problem is to place exit() after the header() location.  But if you do that, the function call on line 71 will not get executed at all, so the function definition does not make any sense in this script.

If you leave it the way it is, the function call on line 71 may or may not get executed, or it may be partially executed.  Taken together, those things create an pleasant code smell.
ASKER
JohnLourdu

Hi Ray,

Thanks Ray, I have updated my code (placing exit() after the header()). Also thanks for your suggestion.

Regards,
John.A
Your help has saved me hundreds of hours of internet surfing.
fblack61