ผลิตภัณฑ์ — FluxFiles

คุณสมบัติ

ทุกสิ่งที่ตัวจัดการไฟล์สมัยใหม่ต้องการ

สร้างขึ้นสำหรับนักพัฒนาที่ต้องการความยืดหยุ่น

หลายที่เก็บข้อมูล

Local, AWS S3, Cloudflare R2, SFTP ผ่าน Flysystem v3 — สลับด้วย config ไม่ต้องแก้โค้ด

ฝังได้ทุกที่

iframe + postMessage SDK UI แยกใช้ Alpine.js (ไม่ต้อง build) ใช้กับทุกเฟรมเวิร์ก

JWT auth + scoping

พาธพรีฟิกซ์ต่อผู้ใช้ สิทธิ์ ไวท์ลิสต์ดิสก์ โหมด owner-only — หรือเริ่มจากพรีเซ็ตบทบาท viewer/editor/admin

พรีเซ็ตบทบาท ACL

ออกโทเคนจากพรีเซ็ต viewer/editor/admin/superadmin — พารามิเตอร์เดียวขยายเป็น claim สิทธิ์ ดิสก์ และขอบเขตที่ถูกต้อง แทนที่จะประกอบเองด้วยมือ

AI auto-tag

Claude / OpenAI vision — alt text, ชื่อ, แท็กอัตโนมัติ

ครอปรูปภาพ

เครื่องมือครอปพร้อมอัตราส่วนภาพสำเร็จรูป

ปรับแต่งรูปภาพ

สร้าง WebP อัตโนมัติ — thumb, medium, large

อัปโหลดแบบ presigned

เบราว์เซอร์อัปโหลดตรงไปยัง S3/R2 — ไม่ใช้แบนด์วิดท์เซิร์ฟเวอร์เลย

อัปโหลดแบบแบ่งส่วน

S3 multipart สำหรับไฟล์ > 10MB

ค้นหาข้อความเต็ม

ค้นหาแบบมีดัชนีตามชื่อ, ชื่อเรื่อง, แท็ก — อิงไฟล์เป็นค่าเริ่มต้น หรือใช้ฐานข้อมูล SQL ของคุณเองเป็นแบ็กเอนด์แบบเลือกได้

เมตาดาต้าบนฐานข้อมูล

โหมดเสริม FLUXFILES_STORAGE_BACKEND=db — เมตาดาต้า ดัชนีค้นหา/โฟลเดอร์ และบันทึก audit จะอยู่ในฐานข้อมูล MySQL/PostgreSQL/SQLite ของคุณเองแทนไฟล์ JSON ไบต์ของไฟล์ยังคงอยู่ในสตอเรจในทั้งสองกรณี

ดำเนินการจำนวนมาก

เลือกหลายไฟล์เพื่อย้าย คัดลอก ลบ ดาวน์โหลด

ถ่ายโอนข้ามดิสก์

คัดลอก/ย้ายระหว่าง Local ↔ S3 ↔ R2

ถังขยะ

ลบแบบกู้คืนได้ ล้างอัตโนมัติ

SEO metadata

หัวข้อ alt คำบรรยาย แท็ก — metadata อ็อบเจ็กต์ S3 (คลาวด์) หรือ sidecar JSON (โลคัล) ค้นหาข้อความเต็ม

โหมดมืด

สว่าง / มืด / อัตโนมัติ ใน UI และ SDK

16 ภาษา

ค่าเริ่มต้นภาษาอังกฤษ ตั้ง locale ผ่าน SDK URL (?locale=) หรือ FLUXFILES_LOCALE อาหรับ RTL

บันทึกการตรวจสอบ

บันทึกการกระทำเขียนทั้งหมด

จำกัดอัตรา

Token bucket ต่อผู้ใช้สำหรับป้องกัน API

โควต้าพื้นที่

จำกัดต่อผู้ใช้ผ่าน JWT claims

BYOB bucket

ผู้ใช้ผูก S3/R2 เอง — credential เข้ารหัสใน JWT (AES-256-GCM)

ตรวจซ้ำ

SHA-256 ตรงกันข้ามอัปโหลดซ้ำ เว้นแต่บังคับเขียนทับ

รีเฟรชโทเคน SDK

onTokenRefresh เมื่อ 401 — รวมรีเฟรช ลองใหม่ updateToken()

Bucket Doctor

วินิจฉัยดิสก์ S3/R2 ใดก็ได้ — ข้อมูลรับรอง อ่าน/เขียน/ลบ presign CORS multipart — พร้อมวิธีแก้ IAM และ CORS ที่พร้อมวาง เพิ่มบักเก็ต BYOB ได้ในไม่กี่นาที

ดิสก์ SFTP

ไดรเวอร์ที่ 3 ต่อจาก S3/R2 — เปลี่ยน VPS หรือโฮสต์ให้เป็นตัวจัดการไฟล์

แก้โค้ด / config

แก้ไฟล์ข้อความและคอนฟิก (wp-config.php, .env) ในเบราว์เซอร์ สไตล์ cPanel

บีบอัดและแตกไฟล์

ดาวน์โหลดที่เลือกเป็น zip หรือแตกไฟล์ในที่ — ป้องกัน zip-slip และ bomb

ลายน้ำ

ใส่ลายน้ำข้อความหรือโลโก้แบบเรียลไทม์เพื่อปกป้อง — ไม่แตะไฟล์ต้นฉบับ

WebP + AVIF ตามต้องการ

ให้บริการรูปทุกขนาดเป็น AVIF/WebP ที่แคชผ่าน URL เดียว (เจรจาด้วย Accept) พร้อม srcset แบบ responsive

สิทธิ์ SFTP

เปลี่ยนสิทธิ์ไฟล์ Unix (chmod) บนดิสก์ SFTP ด้วยกล่องโต้ตอบสไตล์ cPanel

เทอร์มินัล SSH

ฝัง ttyd / gotty / wetty ของคุณเองเป็นเทอร์มินัลในแอปบนดิสก์ SFTP ผ่านclaim ฟรี terminal_pty_url — FluxFiles ไม่มีเชลล์ในตัว

ดีพลอย Git คลิกเดียว

Pull และ reset repo Git บนเซิร์ฟเวอร์ SFTP ของคุณโดยตรงจากตัวจัดการไฟล์ — รูปแบบตายตัว ไม่ใช่เชลล์แบบสุ่ม hooks ปิดไว้เป็นค่าเริ่มต้น

แดชบอร์ดการใช้งาน

ดูพื้นที่จัดเก็บได้ทันที — โควตาพร้อมแยกตามประเภทและโฟลเดอร์

พรีวิวสื่อ

พรีวิวรูป วิดีโอ เสียง และ PDF ในตัว; สื่อโลคัลส่วนตัวสตรีมอย่างปลอดภัย

ติดตั้งด่วน

พร้อมใช้งานใน 2 นาที

composer require fluxfiles/fluxfiles
cp vendor/fluxfiles/fluxfiles/.env.example vendor/fluxfiles/fluxfiles/.env
# vendor/fluxfiles/fluxfiles/.env  (read only from inside the package)
# Real environment variables win over this file and are preferred in production
# (Composer may remove a vendor .env on update).
FLUXFILES_SECRET=<output of: openssl rand -hex 32>
FLUXFILES_ALLOWED_ORIGINS=https://yourapp.com
<?php
require_once 'vendor/autoload.php';
// embed.php is not autoloaded — require it for fluxfiles_token()
require_once 'vendor/fluxfiles/fluxfiles/embed.php';

$token = fluxfiles_token([
    'user'   => 'user-123',
    'perms'  => ['read', 'write', 'delete'],
    'disks'  => ['local'],     // s3 / r2 need their own credentials in .env
    'prefix' => 'user-123/',
    'ttl'    => 3600,
]);
php vendor/bin/fluxfiles serve --port=8080
# then open http://127.0.0.1:8080/public/
composer require fluxfiles/laravel
php artisan vendor:publish --tag=fluxfiles-config
php artisan storage:link
# .env — proxy mode is the default: the API runs through your Laravel routes,
# no separate FluxFiles server is needed.
FLUXFILES_SECRET=<output of: openssl rand -hex 32>

# Only for FLUXFILES_MODE=standalone (FluxFiles on its own server):
# FLUXFILES_MODE=standalone
# FLUXFILES_ENDPOINT=https://fm.yourdomain.com
<?php
// app/FluxFiles/TenantClaims.php — REQUIRED: without a claims resolver
// <x-fluxfiles> renders "not available".
namespace App\FluxFiles;

use FluxFiles\Laravel\ClaimsResolver;
use Illuminate\Contracts\Auth\Authenticatable;

class TenantClaims implements ClaimsResolver
{
    public function resolve(Authenticatable $user): array
    {
        return [
            'prefix' => 'users/' . $user->getAuthIdentifier(),
        ];
    }
}
// config/fluxfiles.php
'claims_resolver' => \App\FluxFiles\TenantClaims::class,
// Laravel 11 / 12 — bootstrap/app.php: exclude the proxy routes from CSRF (else 419)
->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: ['api/fm/*']);
})

// Laravel 10 — app/Http/Middleware/VerifyCsrfToken.php
// protected $except = ['api/fm/*'];
<x-fluxfiles disk="local" mode="picker" height="600px" />
# Not yet on WordPress.org — install the release zip:
# 1. Download fluxfiles-<version>.zip from https://github.com/thai-pc/fluxfiles/releases
# 2. Plugins -> Add New -> Upload Plugin -> Activate
# 3. Settings -> FluxFiles: set the JWT secret (>= 32 bytes) and storage
# 4. Add the shortcode (or the FluxFiles block) to any page or post:
[fluxfiles]
npm install @fluxfiles/node   # Node >= 16
// Express / Next.js route — mint a token from your JS backend (no PHP)
import { createToken } from '@fluxfiles/node';

app.get('/fluxfiles-token', (req, res) => {
    const token = createToken({
        secret: process.env.FLUXFILES_SECRET, // >= 32 bytes
        userId: req.user.id,
        perms: ['read', 'write', 'delete'],
        prefix: `users/${req.user.id}`,
        ttl: 3600,
    });
    res.json({ token });
});
pip install fluxfiles-token
# FastAPI / Django / Flask route — mint a token from your Python backend (no PHP)
import os

from fastapi import Depends
from fluxfiles_token import create_token

@app.get("/fluxfiles-token")
def fluxfiles_token(user=Depends(current_user)):
    token = create_token(
        secret=os.environ["FLUXFILES_SECRET"],  # >= 32 bytes
        user_id=user.id,
        perms=["read", "write", "delete"],
        prefix=f"users/{user.id}",
        ttl=3600,
    )
    return {"token": token}
{
  "mcpServers": {
    "fluxfiles": {
      "command": "npx",
      "args": ["-y", "@fluxfiles/mcp"],
      "env": {
        "FLUXFILES_URL": "<your FluxFiles URL>",
        "FLUXFILES_TOKEN": "<scoped JWT>"
      }
    }
  }
}
# Claude Code (Node >= 18)
claude mcp add fluxfiles -e FLUXFILES_URL=<your FluxFiles URL> -e FLUXFILES_TOKEN=<scoped JWT> -- npx -y @fluxfiles/mcp
# Read-only by default. Opt in to writes:
FLUXFILES_MCP_WRITE=1
# and to move_to_trash:
FLUXFILES_MCP_DELETE=1

agent เข้าถึงได้เฉพาะสิ่งที่ JWT ของมันอนุญาตเท่านั้น — disk, path prefix และสิทธิ์ ควรออกโทเคนแบบอ่านอย่างเดียวที่มีขอบเขตแคบให้

npm install fluxfiles
<!-- or load a pinned CDN build (never @latest) -->
<script src="https://unpkg.com/fluxfiles@1.0.1/fluxfiles.js"></script>
<div id="file-picker" style="height:600px"></div>

<script>
FluxFiles.open({
    endpoint: 'https://your-fluxfiles-host',
    token: 'eyJhbGci...',   // JWT minted by your backend
    disk: 'local',
    mode: 'picker',
    container: '#file-picker',
    onSelect: function(file) {
        console.log('Selected:', file.url);
    },
    async onTokenRefresh() {
        const r = await fetch('/api/auth/refresh-fluxfiles-token');
        const { token } = await r.json();
        return token;
    }
});
</script>
npm install @fluxfiles/react
import { FluxFilesModal } from '@fluxfiles/react';

<FluxFilesModal
    open={open}
    endpoint="https://your-api.com"
    token={token}
    onSelect={(file) => console.log(file)}
    onClose={() => setOpen(false)}
/>
npm install @fluxfiles/vue
<script setup>
import { FluxFilesModal } from '@fluxfiles/vue';
</script>

<FluxFilesModal
    v-model:open="open"
    endpoint="https://your-api.com"
    :token="token"
    @select="onSelect"
    @close="open = false"
/>
docker run -p 8080:80 \
  -e FLUXFILES_SECRET="$(openssl rand -hex 32)" \
  -e FLUXFILES_ALLOWED_ORIGINS=https://yourapp.com \
  -v fluxfiles-data:/app/packages/core/storage \
  ghcr.io/thai-pc/fluxfiles:1.1
# UI: http://localhost:8080/public/
git clone https://github.com/thai-pc/fluxfiles.git
cd fluxfiles/packages/core
composer install
cp .env.example .env
# packages/core/.env — the placeholder secret is rejected, set a real one
FLUXFILES_SECRET=<output of: openssl rand -hex 32>
FLUXFILES_ALLOWED_ORIGINS=http://localhost:8080
# print dev tokens (run from the repo root)
php packages/core/tests/generate-token.php
php -S localhost:8080 router.php

# UI: http://localhost:8080/public/index.html?token=<token>
# ?token= is dev-only — it is stripped from the URL on boot.
# Real apps pass the JWT via the SDK / postMessage, never in a URL.

เมื่อขึ้นโปรดักชัน: ตั้ง FLUXFILES_SECRET ยาวอย่างน้อย 32 ไบต์ และ FLUXFILES_ALLOWED_ORIGINS (หรือ FLUXFILES_FRAME_ANCESTORS) ใช้รากของแพ็กเกจเป็น document root และบล็อก /_fluxfiles/ กับ .env ใน nginx ห้ามใส่ JWT หลักใน URL เด็ดขาด — adapter ส่งผ่าน postMessage DEPLOYMENT.md

ใช้ได้กับ

Laravel WordPress React / Next.js Vue / Nuxt CKEditor 4 CKEditor 5 TinyMCE Summernote Any framework

การเชื่อมต่อ

อะแดปเตอร์พร้อมใช้สำหรับสแต็กของคุณ

อะแดปเตอร์อย่างเป็นทางการฝัง FluxFiles ลงในเฟรมเวิร์กและเอดิเตอร์ที่คุณใช้อยู่แล้วได้ทันที

ใช้ CKEditor หรือ TinyMCE กับที่เก็บข้อมูลของคุณเอง โดยไม่ต้องสมัครสมาชิก CKBox หรือ Tiny Drive FluxFiles เพิ่มปุ่มบนแถบเครื่องมือสำหรับเรียกดูและแทรกไฟล์ ไม่ได้ทดแทนผลิตภัณฑ์เหล่านั้นแบบฟีเจอร์ต่อฟีเจอร์

Laravel
PHP
WordPress
Plugin
React
Component
Vue / Nuxt
Component
CKEditor 4
Plugin
CKEditor 5
Plugin
TinyMCE
Plugin
Summernote
Plugin

การฝัง

ฝังได้ในไม่กี่บรรทัด

โหลด fluxfiles.js ส่ง JWT ที่ออกจากเซิร์ฟเวอร์ แล้ววางตัวจัดการไฟล์เต็มรูปแบบ — หรือโมดัลเลือกไฟล์ — ลงในหน้าใดก็ได้

<!-- npm install fluxfiles, or a pinned CDN build -->
<script src="https://unpkg.com/fluxfiles@1.0.1/fluxfiles.js"></script>

FluxFiles.open({
  endpoint: 'https://fm.example.com',
  token: 'eyJhbGci...',   // JWT from your backend
  disk: 'local',
  mode: 'picker',         // select & close
  theme: 'auto',
  onSelect(file) {
    // { url, key, name, size, disk, meta, variants }
    document.querySelector("#img").src = file.url;
  },
});
<div id="fm" style="height:600px"></div>

FluxFiles.open({
  endpoint: 'https://fm.example.com',
  token: 'eyJhbGci...',
  mode: 'browser',          // full manager, stays open
  container: '#fm',         // omit for a modal overlay
  disks: ['local', 's3', 'r2'],
});

FluxFiles.on('FM_EVENT', (e) => console.log(e.event));
FluxFiles.navigate('/photos/2024');
import { FluxFilesModal } from '@fluxfiles/react';

function Picker({ open, setOpen, token }) {
  return (
    <FluxFilesModal
      open={open}
      endpoint="https://fm.example.com"
      token={token}
      onSelect={(file) => console.log(file.url)}
      onClose={() => setOpen(false)}
    />
  );
}

โทเค็นถูกออกจากฝั่งเซิร์ฟเวอร์ — อย่าส่งซีเคร็ตของคุณไปยังเบราว์เซอร์เด็ดขาด

ทำไมต้อง FluxFiles

สร้างขึ้นสำหรับสิ่งที่คนอื่นลืม

ปัดเพื่อเปรียบเทียบ
คุณสมบัติ FluxFiles elFinder Laravel-FM RichFilemanager Responsive FM
S3 + R2 + Local + SFTP ✓ ⚠ ⚠ ⚠ ✗
ฝังในทุกเฟรมเวิร์ก ✓ ⚠ ✗ ⚠ ✗
JWT auth + scoping ✓ ✗ ✗ ✗ ✗
SEO metadata ✓ ✗ ✗ ✗ ✗
AI auto-tag ✓ ✗ ✗ ✗ ✗
ครอปรูปภาพ ✓ ✓ ✗ ✗ ✗
อัปโหลดแบบแบ่งส่วน ✓ ✗ ✗ ✗ ✗
ค้นหาข้อความเต็ม ✓ ✗ ✗ ✗ ✗
โหมดมืด ✓ ✗ ⚠ ✗ ✗
16 ภาษา ✓ ✓ ✗ ✗ ✗
PHP ≥ 8.1 ✓ ✓ ✗ ✓ ✓
ดูแลอย่างต่อเนื่อง ✓ ✓ ⚠ ✗ ✗
UI สมัยใหม่ ✓ ✗ ⚠ ✗ ✗
ความสามารถ FluxFiles Filestack Uploadcare Cloudinary Supabase Storage
โฮสต์เอง (รันในโครงสร้างพื้นฐานของคุณ) ✓ ✗ ✗ ✗ ⚠
BYOB — บักเก็ตของลูกค้าแต่ละราย ✓ ⚠ ⚠ ✗ ✗
UI ไฟล์แมเนเจอร์แบบฝังได้ ✓ ✓ ✓ ⚠ ✗
โอเพนซอร์ส (MIT) ✓ ✗ ✗ ✗ ✓
ไม่มีค่า SaaS ต่อสตอเรจ / ต่อการอัปโหลด ✓ ✗ ✗ ✗ ⚠
หลายสตอเรจ (S3 / R2 / โลคัล) ✓ ⚠ ✗ ✗ ✗
จำกัดขอบเขตโทเค็นต่อผู้เช่าในตัว ✓ ⚠ ⚠ ⚠ ⚠

การเปรียบเทียบสะท้อนข้อเสนอเริ่มต้นทั่วไป แต่ละผลิตภัณฑ์โดดเด่นในพื้นที่ของตน จุดเฉพาะของ FluxFiles คือการผสานแบบฝังได้ โฮสต์เอง และ bring-your-own-bucket

การเปรียบเทียบนี้เป็นข้อมูล ณ November 2026 จัดทำโดยอิสระ — แจ้งการแก้ไขได้ที่ repo บน GitHub

คำถามที่พบบ่อย

คำถามที่พบบ่อย

การยืนยันตัวตนทำงานอย่างไร?
JWT แบบไร้สถานะ (HS256): คุณออกโทเค็นที่ฝั่งเซิร์ฟเวอร์พร้อม claim ละเอียด (สิทธิ์, ดิสก์, ขอบเขตพาธ, ลิมิต) ผู้ใช้แต่ละคนจึงเห็นเฉพาะสิ่งที่คุณอนุญาต
ผู้ใช้ของฉันต้องมีบัญชี FluxFiles ไหม?
ไม่ต้อง FluxFiles เชื่อถือ JWT ที่ออกจากแอปของคุณเอง จึงเสียบเข้ากับระบบยืนยันตัวตนเดิมได้ทันที — ไม่ต้องมีระบบผู้ใช้แยก
ต้องใช้อะไรในการรัน?
PHP 8.1+ (ทดสอบ 8.1–8.5) พร้อม gd, curl, json, openssl, mbstring, fileinfo (ใช้ Extract ต้องมี zip) และ Composer 2 หรือใช้ Docker image ghcr.io/thai-pc/fluxfiles ชี้ไปที่ดิสก์ ตั้งค่า secret และ origin ที่อนุญาต แล้วเปิดให้บริการ — รันบน VPS เล็ก ๆ ได้
ผู้ใช้แต่ละคนสามารถมีสิทธิ์ต่างกันได้หรือไม่?
ได้ สามารถออก token พร้อม claims แบบละเอียด (อ่าน/เขียน/ลบ, ดิสก์, path prefix, ขีดจำกัดการอัปโหลด, นามสกุลที่อนุญาต, owner-only) หรือใช้หนึ่งใน role preset ที่มีให้สี่แบบ — viewer, editor, admin, superadmin — เพื่อกำหนดขอบเขตของ token ในบรรทัดเดียวแทนการระบุ claim ทีละตัว
ต้องรันฐานข้อมูลเองหรือไม่?
ไม่จำเป็น โดยค่าเริ่มต้น เมทาดาทั้งหมด (ข้อมูลไฟล์ ดัชนีค้นหา บันทึกการตรวจสอบ) จะอยู่ข้างไฟล์ของคุณในรูปแบบ JSON sidecar — ไม่มีอะไรต้องจัดเตรียมหรือสำรองข้อมูลเพิ่มเติม หากต้องการเก็บข้อมูลเหล่านี้ไว้ใน MySQL, PostgreSQL หรือ SQLite ของคุณเอง โหมด FLUXFILES_STORAGE_BACKEND=db ซึ่งเป็นตัวเลือกเสริมจะย้ายไปไว้ที่นั่นแทน โดยไฟล์จริงยังคงอยู่ในสตอเรจของคุณเสมอ
มีข้อจำกัดการใช้งานหรือไม่?
ตัว core เองไม่มีข้อจำกัดที่ตั้งขึ้นมาเอง — ไม่มีเพดานผู้ใช้งานที่ใช้งานจริงต่อเดือน ไม่มีการเร่งให้อัปเกรด คุณกำหนดขีดจำกัดของตัวเองผ่าน JWT claims ได้แก่ โควตาพื้นที่เก็บข้อมูลต่อผู้ใช้ ข้อจำกัดขนาด/นามสกุลไฟล์ที่อัปโหลด และตัวจำกัดอัตรา (rate limiter) ในตัว (ค่าเริ่มต้น 60 ครั้งอ่าน / 10 ครั้งเขียนต่อนาที ปรับแต่งได้)