1

Context

Hello, I would like to list all files in a folder, so I first thought about doing it in php by using the PHP scandir() Function, which resulted in something like that:

<?php
$dir = "/images/";

// Sort in ascending order - this is default
$a = scandir($dir);

// Sort in descending order
$b = scandir($dir,1);

print_r($a);
print_r($b);
?>

Result:

Array
(
[0] => .
[1] => ..
[2] => film1.mkv
[3] => film2.mkv
[4] => film3.mkv
[5] => film4.mkv
)
Array
(
[0] => film4.mkv
[1] => film3.mkv
[2] => film2.mkv
[3] => film1.mkv
[4] => ..
[5] => .
)

But then I realised, as I wanna scan all videos inside my folder in order to display them and give the choice to the local user to clic on any of them; using JavaScript could be a good idea.

Question

Is it possible to do it in Javascript ? Is it a good Idea to use it instead of php ?

EDIT: The final purpose of this is to launch a movie, exactly like Netflix or all famous movies-related websites are doing

7
  • give the choice to the local user to clic on any of them -- what is the intended purpose? What is supposed to happen once they click the file name? Commented Jan 12, 2019 at 18:10
  • The intended purpose is to launch a movie, a kind of Netflix-like Commented Jan 12, 2019 at 18:11
  • 2
    You can't because Javascript is only meant to run through your browser and having access to your system and folders would be a huge security concern. If you're looking to do something like that locally, you could run a node.js server (essentially javascript server) Commented Jan 12, 2019 at 18:14
  • your (php) server should provide kind of an api for your client (website / written in js) to serve those files / videos. Of course you can also use a node server Commented Jan 12, 2019 at 18:22
  • Thank you for your answers, I forgot to say it but my first intention was just to make it run locally like using WAMP or even only the browser Commented Jan 12, 2019 at 18:39

4 Answers 4

3

Browsers can't read a user's files like that. However this is very easy (and common) using Node and the built in 'fs' module.

const { readdirSync } = require('fs');

const PATH_TO_YOUR_FOLDER = '/Users/me/Downloads';

console.log(readdirSync(PATH_TO_YOUR_FOLDER));
// output: array of the file names in my downloads directory

You'll need to install Node: https://nodejs.org/en/

Here's the fs documentation: https://nodejs.org/api/fs.html#fs_fs_readdirsync_path_options

Then save the code above in a .js file, and run it with node (using a terminal):

node ./my-code.js
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your help ! I'll get through this and give you some feedback later ;)
2

Given your comment on making something similar to a Netflix clone, my suggested advice would be to make a PHP endpoint that exports the file list as JSON. That being said, I do not suggest you build a file browser that allows user input as this will, in many cases, open you up to directory traversal attacks and a malicious user may be able to gain access to your entire server. It can be done properly, but is tricky.

Instead, why not have a database that contains file names, types, paths, keywords, thumbnail image paths, etc. Then use client side javascript to make requests via ajax to a PHP script that handles the database access and fully controls the file access. In this way, when a user clicks on a video, you can then call another endpoint that initiates a websocket for video streaming and the user cannot maliciously wander around in your server or download/steal your video files directly.

Here is an example of listing some files from your server. For code simplicity, I am assuming jQuery here, but you can use another library or native XMLHttpRequest object:

$.ajax({
    url: '/movies/list-all.php',
    method: 'GET',
    dataType: 'json'
}).done(function(data) {
    if (typeof data === 'object' && typeof data !== null) {
        // List the movies
        for(var movie in data.movies) {
            var movieDiv = '<div class="movie-item" data-id="' + movie.id + '">' +
                '<img src="' + movie.thumbnail_path + '"><br>' +
                '<p>' + movie.title + '</p>' +
                '</div>';
            $('#my-container-div').append(movieDiv);
        }
    }
});

Example PHP endpoint to list movies:

<?php

    /**
     * list-all.php
     *
     * Assumes you have a PDO database connection setup already here as $db.
     */

    $stmt = $db->query("SELECT * FROM movies");
    if ($stmt instanceof PDOStatement) {
        $movies = $stmt->fetchAll();
        $response = (object) [
            'total'  => count($movies),
            'movies' => $movies,
        ];
    } else {
        $response = (object) [
            'total' => 0,
            'movies' => [],
        ]
    }

    header('Content-Type: application/json');
    echo(json_encode($response));

Demo (sort of):

var movieData = {
  count: 3,
  movies: [{
      id: 1,
      title: "Movie A",
      thumb: "https://via.placeholder.com/150"
    },
    {
      id: 2,
      title: "Movie B",
      thumb: "https://via.placeholder.com/150"
    },
    {
      id: 3,
      title: "Movie C",
      thumb: "https://via.placeholder.com/150"
    },
  ]
};

$(document).ready(function() {

  if (typeof movieData === 'object' && typeof movieData !== null) {
    // List the movies
    for (var i in movieData.movies) {
      var movie = movieData.movies[i];
      var movieDiv = '<div class="movie-item" data-id="' + movie.id + '">' +
        '<img src="' + movie.thumb + '"><br>' +
        '<p>' + movie.title + '</p>' +
        '</div>';
      $('#movies').append(movieDiv);
    }
  }

});
.movie-item {
  display: inline-block;
  border: 2px solid #DDD;
  margin: 10px;
  text-align: center;
}

.movie-item:hover {
  border: 2px solid #00aaca;
  cursor: pointer;
}

.movie-item p {
  color: #00aaca;
  font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>

<head></head>

<body>
  <h1>Movies</h1>
  <div id="movies"></div>
</body>

</html>

4 Comments

the OP may not know what an "endpoint" is. but this is what i tried to say in my comment :) +1
Ah, hadn't seen the new comments while writing my answer. I can further explain and provide code examples for anything OP is unclear on.
First of all thank you for your answer, my first intention was to run it like on local from an usb key or even the owner computer, just to display available movies on the folder nicely instead of browsing windows folder, so I didn't have the intention to upload this site online a day
Thank you for the update @Jeremy I appreciate, Must I use a database ? because the Idea would be to have a "Local Netflix" that I could give to anyone launchable from an USB key, and then they just have to put the movies into the folder, and my local website do the tricks (display them nicely within an interface) when they click on the index.html, do you think this is possible?
0

No, unless you run node server.

what you can do is, print $a or $b, inside the html, it looks like this:

<html>
  <head>
    <script>
      var files = <?php echo $a ?>
      // then do whatever to display it
  </head>
</html>

i might be not accurate to use echo, you're welcome to print it any other way using print or printr. And also u might need extra work to print the $a as correct js object

Comments

0

EXAMPLE 1

PHP Alone To get File contents.

include 'db.php';// Your DB connection file
$dir = "/images/";
$fi = scandir($dir);
$num_fi = count($fi)-2;
$dh = opendir($dir);
$file = readdir($dh);
$res = "";$i=0;
if (is_dir($dir)){
    if ($dh = opendir($dir)){
        if ($i < $num_fi){

            while (false !== ($file = readdir($dh))){
                 if($file !== "." && $file !== ".." && $file !== ".htaccess" && $file !== "Thumbs.db"){
            $i++;
            echo "<div><iframe src=\"".$dir.$files."\"></iframe><div>" 
            } else {
            echo "<div>No Videos.</div>";
            }
        }
    }   
}
closedir($dh);

EXAMPLE 2

Ajax example would take 2 files one with your HTML and Javascript and another file to call your PHP. The Ajax is for calling with an event like onclick, or you can just call the ajax function like below.

The PHP will get file contents and place each video inside an iframe through the while loop. Name the PHP file videos.php the same name as the file Ajax looks for.

if(isset($_POST['data'])){
include 'db.php';// Your DB connection file
$dir = "/images/";
$fi = scandir($dir);
$num_fi = count($fi)-2;
$dh = opendir($dir);
$file = readdir($dh);
$res = "";$i=0;
if (is_dir($dir)){
if ($dh = opendir($dir)){
if ($i < $num_fi){

while (false !== ($file = readdir($dh))){
if($file !== "." && $file !== ".." && $file !== ".htaccess" && $file !== "Thumbs.db"){
$i++;
$res .= "<div><iframe src=\"".$dir.$files."\"></iframe><div>" 
} else {
$res .= "<div>No Videos.</div>";}
}
}
closedir($dh);
} 
echo $res;

This is the Javascript Ajax Call. It calls your PHP file with this line RequestObject.open("POST", "videos.php") to do the work.

var RequestObject = false;
if (window.XMLHttpRequest) {
  RequestObject = new XMLHttpRequest();
} else if (window.ActiveXObject) {
  RequestObject = new ActiveXObject("Microsoft.XMLHTTP");
}

function chooseVideos() {
  if (RequestObject) {
    RequestObject.open("POST", "videos.php");
    RequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    RequestObject.onreadystatechange = function() {
      if (RequestObject.readyState == 4 && RequestObject.status == 200) {
        document.getElementById('videoPanel').innerHTML = RequestObject.responseText;
      }
    }
    var data = "vidData";
    RequestObject.send("data=" + data);
  }
  return false;
}

chooseVideos();
<form method="post">
  <div id="videoPanel"></div>
</form>

Above is your HTML Container To show the Results of the Ajax call document.getElementById('videoPanel').innerHTML = RequestObject.responseText;

1 Comment

Thank you a lot for your answer, do you think there is please a way to make a working snipet of it just to make it more clear to me ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.