PDA

View Full Version : تغییر نام عکس با id رکورد ذخیره شده



hessam2008
چهارشنبه 15 مهر 1394, 09:52 صبح
سلام وقت بخیر من یک فرم ثبت نامی دارم. که اطلاعات فردی را میگیرم و داخل دیتابیس ذخیره میکنم حالا میخوام که عکسی که کاربر آپلود میکنه با ایدی دیتابیش همان بشه و توی پوشه اپلود بشه چه جوری باید پیدا کنم دوستان کسی هست کمک کنه ؟

H:Shojaei
چهارشنبه 15 مهر 1394, 10:47 صبح
کاربر رو که تو دیتابیس اضافه کردین همونجا lastInsertId رو بگیرید از جدول کاربران نام فایل آپلودی رو برابر با این id بذارید و آپلود رو انجام بدین...

hessam2008
چهارشنبه 15 مهر 1394, 10:55 صبح
کاربر رو که تو دیتابیس اضافه کردین همونجا lastInsertId رو بگیرید از جدول کاربران نام فایل آپلودی رو برابر با این id بذارید و آپلود رو انجام بدین...

ممنونم بنظرتون این مشکل پیش نمیاد که چندکاربر همزمان اطلاعاتشون رو وارد کنن ؟با عکس ها بعد هماهنگ نباشه؟

به طور مثال دوتا کاربر همزمان ارسال کنند حالا lastInsertId به کاربر دومی به اولی بره

H:Shojaei
چهارشنبه 15 مهر 1394, 13:01 عصر
ممنونم بنظرتون این مشکل پیش نمیاد که چندکاربر همزمان اطلاعاتشون رو وارد کنن ؟با عکس ها بعد هماهنگ نباشه؟

به طور مثال دوتا کاربر همزمان ارسال کنند حالا lastInsertId به کاربر دومی به اولی بره
این اتفاق خیلی به ندرت پیش میاد و تو سیستم های کوچیک هم شاید اصلا هیچوقت رخ نده...
البته باید id رو دقیقا بعد از اجرای کوئری بگیرید...
باز هم اگر بخواید میتونید با نام کاربری که ثبت شده یا فیلدی که یکتا هست واسه کاربر یه select دیگه از دیتابیس بگیرید و مقدار دقیق id رو بگیرید نگران اون خطای ارسال همزمان هم اینطوری نیستید...

Unique
چهارشنبه 15 مهر 1394, 22:40 عصر
این اتفاق خیلی به ندرت پیش میاد و تو سیستم های کوچیک هم شاید اصلا هیچوقت رخ نده...
این اتفاق هیچوقت نمیفته،‌

ravand
پنج شنبه 16 مهر 1394, 07:08 صبح
کاربر رو که تو دیتابیس اضافه کردین همونجا lastInsertId رو بگیرید از جدول کاربران نام فایل آپلودی رو برابر با این id بذارید و آپلود رو انجام بدین...
الان بخوای آخرین آی دی رو بگیری اول باید رکورد ثبت بشه که شما آخرین آی دی رو بگیری. شاید طرف بخواد آدرس عکس را همراه با رکورد ثبت بکنه؟ مگر اینکه منظور شما این باشه که شماره ی رکورد قبلی رو بگیریم؟ که در این صورت شماره ی رکورد قبلی میشه نام عکس مورد نظر.
من امدم نام عکس را از تابع time() و rand گرفتم ولی در عوض قبلش چک کردم که این آدرس قبلا وجود نداشته باشه.

H:Shojaei
پنج شنبه 16 مهر 1394, 08:18 صبح
این اتفاق هیچوقت نمیفته،‌
بله هواسم نبود lastInsertId واسه اون کوئری که اجرا شده مقدار برمیگردونه متشکر...

الان بخوای آخرین آی دی رو بگیری اول باید رکورد ثبت بشه که شما آخرین آی دی رو بگیری. شاید طرف بخواد آدرس عکس را همراه با رکورد ثبت بکنه؟
خوب سوال این بود که اسم عکس رو با id کاربر ذخیره کنه...
روشی که شما گفتید هم درسته و این که نیاز به چک کردن نیست که تکراری باشه یا نباشه در هر لحظه time یک عدد متفاوت برمیگردونه و باز تابع rand رو هم که کنارش اعمال میکنید واقعا درصد این که ۲ کاربر دقیقا در یک ثانیه یک عملیات انجام بدن و تابع rand هم دقیقا یک مقدار برگردونه تو این زمان چقدره!؟ فکر نکنم نیاز به چک کردن تکراری بودن باشه...

ravand
پنج شنبه 16 مهر 1394, 09:03 صبح
بله هواسم نبود lastInsertId واسه اون کوئری که اجرا شده مقدار برمیگردونه متشکر...

خوب سوال این بود که اسم عکس رو با id کاربر ذخیره کنه...
روشی که شما گفتید هم درسته و این که نیاز به چک کردن نیست که تکراری باشه یا نباشه در هر لحظه time یک عدد متفاوت برمیگردونه و باز تابع rand رو هم که کنارش اعمال میکنید واقعا درصد این که ۲ کاربر دقیقا در یک ثانیه یک عملیات انجام بدن و تابع rand هم دقیقا یک مقدار برگردونه تو این زمان چقدره!؟ فکر نکنم نیاز به چک کردن تکراری بودن باشه...
شما متوجه منظور من نشدی. ببینید کی این دستور
lastInsertId شماره ی رکورد رو بر میگردونه؟ وقتی که مقادیر وارد دیتابیس شد درسته؟ بعد این موقع شما میخوای شماره ی رکوردی که ایجاد شده رو بگیری بذاری برای نام عکس درسته؟
خب شاید یکی بخواد نام عکس رو همون موقع ثبت رکورد وارد دیتابیس کنه.

djtrex
پنج شنبه 16 مهر 1394, 09:56 صبح
ممنونم بنظرتون این مشکل پیش نمیاد که چندکاربر همزمان اطلاعاتشون رو وارد کنن ؟با عکس ها بعد هماهنگ نباشه؟

به طور مثال دوتا کاربر همزمان ارسال کنند حالا lastInsertId به کاربر دومی به اولی بره

من نقل و قول می کنم از سایت mysql:



Using LAST_INSERT_ID() (https://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id) and AUTO_INCREMENT columns simultaneously from multiple clients is perfectly valid. Each client will receive the last inserted ID for the last statement that client executed.




The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.


https://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html
https://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

همونطور که مشخصه lastinsertid در mysql وابسته به کانکشن شماست. یعنی حتی اگر هم زمان فرستاده بشه lastinsertid مربوط به هر کانکشن فرستاده میشه.

اطلاعات بیشتر:
http://stackoverflow.com/questions/22126830/reliable-or-not-pdo-lastinsertid-when-using-transactions

-------------
همانطور که قبلا هم گفته شد میتونید از یک مقدار رندوم هم برای اینکار استفاده کنید (uuid v4 یا uuid v1 مثلا!)

H:Shojaei
پنج شنبه 16 مهر 1394, 10:17 صبح
شما متوجه منظور من نشدی. ببینید کی این دستور
lastInsertId شماره ی رکورد رو بر میگردونه؟ وقتی که مقادیر وارد دیتابیس شد درسته؟ بعد این موقع شما میخوای شماره ی رکوردی که ایجاد شده رو بگیری بذاری برای نام عکس درسته؟
خب شاید یکی بخواد نام عکس رو همون موقع ثبت رکورد وارد دیتابیس کنه.

متوجه شدم...
و جواب هم دادم سوالی که شده تو این تاپیک توسط ایجاد کننده تاپیک مربوط به اینه که نام عکس بشه id رکوردی که ثبت میشه و عکس *داخل پوشه* آپلود بشه موضوع این مورده...
وگر نه روش شما رو خود من هم استفاده میکنم و تلفیقی از زمان و یه مقدار رندوم رو میگذارم واسه نام عکس...

hessam2008
پنج شنبه 16 مهر 1394, 10:33 صبح
ممنون از مهر و محبت همه دوستان ، بهترین روش پیشنهادی شما چیه که همان را بنویسم ؟بین این چندتا راه

Mohammadsgh
پنج شنبه 16 مهر 1394, 10:42 صبح
من جای شما بودم از تابع time به همراه تابع rand استفاده می کردم.شبیه کار آقای ravand

Unique
جمعه 17 مهر 1394, 00:53 صبح
من جای شما بودم از تابع time به همراه تابع rand استفاده می کردم.شبیه کار آقای ravand
به نظر من بهترین روش همینه که id رکورد ایجاد شده را بگیریم و بر حسب اون فایل را نامگذاری کنیم توی سرور (جناب شجاعی یه اشتباه کوچیک داشتن که من و djtrex تذکر دادیم و خودشون هم تایید کردند و همیشه id همون مقدار یکتا خواهد بود که توی پایگاه ثبت میشه و با client های دیگه هیچوقت قاطی نمیشه). در زمان insert نام اصلی فایل را ذخیره میکنیم تا اگه خواستیم فایل را برای دانلود بگذاریم بتونیم با اسم واقعیش بفرستیم برای بازدید کننده.

یکی از مهمترین برتری های استفاده از شماره id رکورد اینه که در زمان نمایش ، پروسس ، حذف کردن (چه یک فایل چه جند فایل) نیاز نیست query بزنیم تا اسمی که روی دیسک ذخیره کردیم را در بیاریم،

ravand
جمعه 17 مهر 1394, 06:49 صبح
به نظر من بهترین روش همینه که id رکورد ایجاد شده را بگیریم و بر حسب اون فایل را نامگذاری کنیم توی سرور (جناب شجاعی یه اشتباه کوچیک داشتن که من و djtrex تذکر دادیم و خودشون هم تایید کردند و همیشه id همون مقدار یکتا خواهد بود که توی پایگاه ثبت میشه و با client های دیگه هیچوقت قاطی نمیشه). در زمان insert نام اصلی فایل را ذخیره میکنیم تا اگه خواستیم فایل را برای دانلود بگذاریم بتونیم با اسم واقعیش بفرستیم برای بازدید کننده.

یکی از مهمترین برتری های استفاده از شماره id رکورد اینه که در زمان نمایش ، پروسس ، حذف کردن (چه یک فایل چه جند فایل) نیاز نیست query بزنیم تا اسمی که روی دیسک ذخیره کردیم را در بیاریم،
بیشتر توضیح میدم: ببینید مشکل اینجاست که شما اولاً باید رکورد رو ثبت کنی تا بتونی با استفاده از دستور
lastinsertid شماره ی رکوردی که ثبت شد رو بگیری. در این صورت دگه نمیتونی نام عکس را هم با همین شماره ی رکورد قرار بدی.
و اگه بیای و یک عدد به شماره ی رکورد قبلی اضافه کنی و با نام عکس از رکورد بعدی قرار بدی . امکان داره قبلا چند رکورد حذف شده باشه. و نام آدرس عکس ها جابجا و قاطی بشه.
مثلاً آخرین رکورد شما 42 هست وقتی یکی بهش اضافه کنی و به نام آدرس عکس بذاری میشه 43.jpg در صورتی که مثلاً دو تا رکورد بعد قبلا حذف شده و باید بشه 45.jpg
نمیدونم شاید من باید یه کاری رو باید انجام بدم که انجام ندادم. برای همین این مشکل پیش امده.
پیشنهادتون برای حل این مشکل چیه؟

H:Shojaei
جمعه 17 مهر 1394, 10:30 صبح
بیشتر توضیح میدم: ببینید مشکل اینجاست که شما اولاً باید رکورد رو ثبت کنی تا بتونی با استفاده از دستور
lastinsertid شماره ی رکوردی که ثبت شد رو بگیری. در این صورت دگه نمیتونی نام عکس را هم با همین شماره ی رکورد قرار بدی.
و اگه بیای و یک عدد به شماره ی رکورد قبلی اضافه کنی و با نام عکس از رکورد بعدی قرار بدی . امکان داره قبلا چند رکورد حذف شده باشه. و نام آدرس عکس ها جابجا و قاطی بشه.
مثلاً آخرین رکورد شما 42 هست وقتی یکی بهش اضافه کنی و به نام آدرس عکس بذاری میشه 43.jpg در صورتی که مثلاً دو تا رکورد بعد قبلا حذف شده و باید بشه 45.jpg
نمیدونم شاید من باید یه کاری رو باید انجام بدم که انجام ندادم. برای همین این مشکل پیش امده.
پیشنهادتون برای حل این مشکل چیه؟

کلا کاری که جناب unique گفتن مشکلی نداره نمیدونم چرا اسرار بر این میکنید من هم ازین به بعد همین روش رو میرم چون بار اضافی روی دیتابیس نداره و همچنین همیشه آی دی کاربر رو که تو سشن خواهم داشت مشکل کوئری زدن وقتی جایی میخوام عکس رو نمایش بدم هم دیگه ندارم هرچند میشه عکس رو هم نگه دارم تو سشن ولی وقتی روشی بهتر هست چرا نه...
یه توضیح کلی هم میدم در این رابطه یکم روشنتر بشه موضوع هرچند میدونم دوستان حرفه ای هستن و نیاز هم نیست...
رکوردی که ثبت میشه آیدی اون رو میگیریم و نام عکس رو میذاریم برابر به همین آی دی و عکس رو آپلود میکنیم اینجا نیازی نیست نام عکسی تو دیتابیس داشته باشیم آیدی رکورد نام عکسه...
واسه وقتی که اگر عکس آپلود نشد میایم قبل این که آپلود رو انجام بدیم آیدی گرفته شده رو توی یک سشن نگه میداریم و اگر خطایی بود یه کادر فقط آپلود به کاربر نمایش میدیم که فقط عکس رو آپلود کنه و عکسی که آپلود کرد رو با سشنی که داریم نامگذاری میکنیم...
فکر نمیکنم تو این مورد دیگه مشکلی باشه...

ravand
جمعه 17 مهر 1394, 10:42 صبح
این نوشته حذف شد.

Unique
جمعه 17 مهر 1394, 12:54 عصر
ببینید مشکل اینجاست که شما اولاً باید رکورد رو ثبت کنی تا بتونی با استفاده از دستور
lastinsertid شماره ی رکوردی که ثبت شد رو بگیری. در این صورت دگه نمیتونی نام عکس را هم با همین شماره ی رکورد قرار بدی.

جناب Ravand مشکل شما به خاطر دقت نکردن به یک موضوع خیلی کوچیکه ! وقتی ما عکس یا هر فایلی را با استفاده از شماره ID رکورد ذخیره میکنیم مثلا بعد از insert رکورد جدید میشه 42 و ما فایل را با نام 42.jpg توی مسیر مورد نظر ذخیره میکنیم. اصلا نیاز نیست مسیر جدید یا نام جدید را توی پایگاه ثبت کنیم. چون با داشتن ID و اینکه ما بواسطه منطق برنامه میدونیم مسیر ذخیره سازی هر چیزی کجاست پس همیشه میتونیم به فایل دسترسی پیدا کنیم.

حالا من میدونم مشکل بعدی شما چیه ، اگه ما برای یک فیلد عکس مثلا jpg و png و ... را قبول کنیم حالا از کجا بدونیم بعد از id توی مسیرمون موقع فراخونی عکس چه پسوندی را بزنیم ؟ خوب پاسخش اینه که شما در زمان insert باید نام واقعی را از FILES_$ بگیری و توی فیلد ذخیره کنی تا دو مزیت داشته باشه ، اول اینکه بتونی پسوند عکس را به دست بیاری و مسیر صحیح را با ID رکورد بسازی و دوم اینکه در زمان دانلود فایل را با همون نامی که کاربر upload کرده بهش برگردونی نه نامی با شماره ID رکورد.

نکته: حتی اگه خیلی دوست داری نام و مسیر جدید را ذخیره کنی میتونی فیلد نام عکس را در زمان insert برابر null بگذاری و بعد از دریافت آخرین رکورد و ذخیره عکس ، نام و مسیر را توی جدول update کنی. بدیش اینه دو تا query میزنی اما خوب بار خاصی روی سرور نخواهد داشت. بدی دومش اینه نام واقعی فایل را دیگه نداری مگه اینکه دو تا فیلد برای نام قبلی و جدید در نظر بگیری گه کار اشتباهیه از نظر من.

موفق باشین

ravand
جمعه 17 مهر 1394, 14:20 عصر
جناب Ravand مشکل شما به خاطر دقت نکردن به یک موضوع خیلی کوچیکه ! وقتی ما عکس یا هر فایلی را با استفاده از شماره ID رکورد ذخیره میکنیم مثلا بعد از insert رکورد جدید میشه 42 و ما فایل را با نام 42.jpg توی مسیر مورد نظر ذخیره میکنیم. اصلا نیاز نیست مسیر جدید یا نام جدید را توی پایگاه ثبت کنیم. چون با داشتن ID و اینکه ما بواسطه منطق برنامه میدونیم مسیر ذخیره سازی هر چیزی کجاست پس همیشه میتونیم به فایل دسترسی پیدا کنیم.

حالا من میدونم مشکل بعدی شما چیه ، اگه ما برای یک فیلد عکس مثلا jpg و png و ... را قبول کنیم حالا از کجا بدونیم بعد از id توی مسیرمون موقع فراخونی عکس چه پسوندی را بزنیم ؟ خوب پاسخش اینه که شما در زمان insert باید نام واقعی را از FILES_$ بگیری و توی فیلد ذخیره کنی تا دو مزیت داشته باشه ، اول اینکه بتونی پسوند عکس را به دست بیاری و مسیر صحیح را با ID رکورد بسازی و دوم اینکه در زمان دانلود فایل را با همون نامی که کاربر upload کرده بهش برگردونی نه نامی با شماره ID رکورد.

نکته: حتی اگه خیلی دوست داری نام و مسیر جدید را ذخیره کنی میتونی فیلد نام عکس را در زمان insert برابر null بگذاری و بعد از دریافت آخرین رکورد و ذخیره عکس ، نام و مسیر را توی جدول update کنی. بدیش اینه دو تا query میزنی اما خوب بار خاصی روی سرور نخواهد داشت. بدی دومش اینه نام واقعی فایل را دیگه نداری مگه اینکه دو تا فیلد برای نام قبلی و جدید در نظر بگیری گه کار اشتباهیه از نظر من.

موفق باشین
حرف هاتون کاملاً منطقیه. از بس عادت کردیم که ادرس عکس رو توی جدول ذخیره کنیم و برای همین به این موضوع ساده اصلا فکر نکرده بودم.:لبخند:
من روش اول شما را استفاده میکنم. در رابطه با ویرایشش هم خب میام همون شماره ی رکورد رو به عکس جدید میدم. و خب در ویرایش،هم نیازی به ثبت نام عکس در دیتابیس هم نیست. چون پسوندش برام مهم نیست.
مگر اینکه بخوام برای کسی برنامه بنویسم.
در رابطه با امنیتش چه پیشنهادی دارید؟ من با GD کار میکردم ولی بعداً فهمیدم تصاویر با پسوند gif از حالت متحرک خارج میشن.
یکی پیشنهاد ImageMagick را داد که بعداً گفت اینم یه مشکلی از لحاظ امنیت داره. تازه توی هاست های اشتراکی هم نمیشه ازش استفاده کرد.

Unique
شنبه 18 مهر 1394, 00:56 صبح
در رابطه با امنیتش چه پیشنهادی دارید؟ من با GD کار میکردم ولی بعداً فهمیدم تصاویر با پسوند gif از حالت متحرک خارج میشن.
منظورتون رت متوجه نمیشم که از حالت متحرک خارج میشه ؟! من تا حالا پروژه داشتم که کاربر نیاز داشته باشه gif متحرک upload کنه اما جالبه بدونم منظورتون چیه ؟ از کدوم تابع استفاده میکنید که مشکل امنیتی دارین ؟

اگه واقعا امنیت تا این اندازه مهمه میتونی فایل را با curl برای سایت http://www.virustotal.com بفرستی و مطمئن بشی مشکلی نداره.

ravand
شنبه 18 مهر 1394, 06:49 صبح
منظورتون رت متوجه نمیشم که از حالت متحرک خارج میشه ؟! من تا حالا پروژه داشتم که کاربر نیاز داشته باشه gif متحرک upload کنه اما جالبه بدونم منظورتون چیه ؟ از کدوم تابع استفاده میکنید که مشکل امنیتی دارین ؟

اگه واقعا امنیت تا این اندازه مهمه میتونی فایل را با curl برای سایت http://www.virustotal.com بفرستی و مطمئن بشی مشکلی نداره.
یعنی منظورتون اینه که فایل gif از حالت متحرک خارج نمیشه؟
من الان با کمک GD و دستورات دگه یه عکس رو آپلود میکنم. در صورتی که قبلاً این عکس متحرک بوده الان دیگه هیچ حرکتی نداره. شما تا حالا امتحان نکردید؟

Unique
یک شنبه 19 مهر 1394, 01:27 صبح
یعنی منظورتون اینه که فایل gif از حالت متحرک خارج نمیشه؟
من الان با کمک GD و دستورات دگه یه عکس رو آپلود میکنم. در صورتی که قبلاً این عکس متحرک بوده الان دیگه هیچ حرکتی نداره. شما تا حالا امتحان نکردید؟

لطفا کد بگذارین تا ببینم چیکار میکنید.

ravand
یک شنبه 19 مهر 1394, 07:37 صبح
اینو مهندس شهرکی نوشت:

<form enctype="multipart/form-data" method="post">
<input type="file" name="photo"/>
<input type="submit" value="ارسال"/>
</form><br/>
<?php
if(isset($_FILES['photo']['name']) && $_FILES['photo']['error'] == 0) {
$photo = &$_FILES['photo'];
switch(strtolower($photo['type'])) {
case 'image/gif':
$src = ImageCreateFromGIF($photo['tmp_name']);
break;
case 'image/jpeg':
$src = ImageCreateFromJPEG($photo['tmp_name']);
break;
case 'image/png':
$src = ImageCreateFromPNG($photo['tmp_name']);
ImageAlphaBlending($src, false);
ImageSaveAlpha($src, true);
break;
case 'image/bmp':
$src = ImageCreateFromWBMP($photo['tmp_name']);
break;
default:
exit();
break;
}
$dst = ImageCreateTrueColor(ImageSX($src), ImageSY($src));
$white = ImageColorAllocate($dst, 255, 255, 255);
ImageFilledRectangle($dst, 0, 0, ImageSX($src), ImageSY($src), $white);
ImageCopyResampled($dst, $src, 0, 0, 0, 0, ImageSX($src), ImageSY($src), ImageSX($src), ImageSY($src));
ImageJPEG($dst, 'upload/' . substr($photo['name'], 0, strrpos($photo['name'], '.')) . '.jpg', 100);
ImageDestroy($dst);
ImageDestroy($src);
}
?>
میتونستم از ImageCreateFromGIF برای امنیتش استفاده کنم. ولی خب دستورات بعدی برای اطمینان بیشتر بود.

Unique
یک شنبه 19 مهر 1394, 14:20 عصر
مشکل اینکه animation را از دست میدین از این خطه :

ImageJPEG($dst, 'upload/' . substr($photo['name'], 0, strrpos($photo['name'], '.')) . '.jpg', 100);

اینجا هم باید switch بگذارین و از توابع imagejpeg و imagepng و imagegif و ... بر اساس نوع فایل استفاده کنید.

ravand
یک شنبه 19 مهر 1394, 14:34 عصر
مشکل اینکه animation را از دست میدین از این خطه :

ImageJPEG($dst, 'upload/' . substr($photo['name'], 0, strrpos($photo['name'], '.')) . '.jpg', 100);

اینجا هم باید switch بگذارین و از توابع imagejpeg و imagepng و imagegif و ... بر اساس نوع فایل استفاده کنید.
درسته حق با شماست. برای منم عجیب بود. گفتم چرا اینو استفاده نکرده؟! ولی چون از امنیت چیزی سر در نمیارم
با خودم گفتم لابد مثلاً این فرمت امنیتش بیشتره. بعد هم که پیشنهاد ImageMagick بهم داده شد.